303 config.add(specificT::configSection() +
".threadPrio",
"", specificT::configSection() +
".threadPrio", argType::Required, specificT::configSection(),
"threadPrio",
false,
"int",
"The real-time priority of the shmimMonitor thread.");
305 config.add(specificT::configSection() +
".cpuset",
"", specificT::configSection() +
".cpuset", argType::Required, specificT::configSection(),
"cpuset",
false,
"string",
"The cpuset for the shmimMonitor thread.");
307 config.add(specificT::configSection() +
".shmimName",
"", specificT::configSection() +
".shmimName", argType::Required, specificT::configSection(),
"shmimName",
false,
"string",
"The name of the ImageStreamIO shared memory image. Will be used as /tmp/<shmimName>.im.shm.");
309 config.add(specificT::configSection() +
".getExistingFirst",
"", specificT::configSection() +
".getExistingFirst", argType::Required, specificT::configSection(),
"getExistingFirst",
false,
"bool",
"If true an existing image is loaded. If false we wait for a new image.");
312 m_shmimName = derived().configName();
332 m_indiP_shmimName = pcf::IndiProperty(pcf::IndiProperty::Text);
333 m_indiP_shmimName.setDevice(derived().configName());
334 m_indiP_shmimName.setName(specificT::indiPrefix() +
"_shmimName");
335 m_indiP_shmimName.setPerm(pcf::IndiProperty::ReadOnly);
336 m_indiP_shmimName.setState(pcf::IndiProperty::Idle);
337 m_indiP_shmimName.add(pcf::IndiElement(
"name"));
338 m_indiP_shmimName[
"name"] = m_shmimName;
340 if (derived().registerIndiPropertyNew(m_indiP_shmimName,
nullptr) < 0)
342 #ifndef SHMIMMONITOR_TEST_NOLOG
343 derivedT::template log<software_error>({__FILE__, __LINE__});
349 m_indiP_frameSize = pcf::IndiProperty(pcf::IndiProperty::Number);
350 m_indiP_frameSize.setDevice(derived().configName());
351 m_indiP_frameSize.setName(specificT::indiPrefix() +
"_frameSize");
352 m_indiP_frameSize.setPerm(pcf::IndiProperty::ReadOnly);
353 m_indiP_frameSize.setState(pcf::IndiProperty::Idle);
354 m_indiP_frameSize.add(pcf::IndiElement(
"width"));
355 m_indiP_frameSize[
"width"] = 0;
356 m_indiP_frameSize.add(pcf::IndiElement(
"height"));
357 m_indiP_frameSize[
"height"] = 0;
359 if (derived().registerIndiPropertyNew(m_indiP_frameSize,
nullptr) < 0)
361 #ifndef SHMIMMONITOR_TEST_NOLOG
362 derivedT::template log<software_error>({__FILE__, __LINE__});
368 struct sigaction act;
372 act.sa_flags = SA_SIGINFO;
377 if (sigaction(SIGUSR1, &act, 0) < 0)
379 std::string logss =
"Setting handler for SIGUSR1 failed. Errno says: ";
380 logss += strerror(errno);
382 derivedT::template log<software_error>({__FILE__, __LINE__, errno, 0, logss});
387 if (derived().threadStart(m_smThread, m_smThreadInit, m_smThreadID, m_smThreadProp, m_smThreadPrio, m_smCpuset, specificT::configSection(),
this, smThreadStart) < 0)
389 derivedT::template log<software_error>({__FILE__, __LINE__});
437 m_smThreadID = syscall(SYS_gettid);
440 while (m_smThreadInit ==
true && derived().shutdown() == 0)
449 while (derived().shutdown() == 0)
451 while ((derived().state() !=
stateCodes::OPERATING || m_shmimName ==
"") && !derived().shutdown() && !m_restart)
456 if (derived().shutdown())
471 ImageStreamIO_filename(SM_fname,
sizeof(SM_fname), m_shmimName.c_str());
472 SM_fd = open(SM_fname, O_RDWR);
476 derivedT::template log<text_log>(
"ImageStream " + m_shmimName +
" not found (yet). Retrying . . .", logPrio::LOG_NOTICE);
486 if (ImageStreamIO_openIm(&m_imageStream, m_shmimName.c_str()) == 0)
488 if (m_imageStream.md[0].sem <= m_semaphoreNumber)
490 ImageStreamIO_closeIm(&m_imageStream);
497 ImageStreamIO_filename(SM_fname,
sizeof(SM_fname), m_shmimName.c_str());
500 int rv = stat(SM_fname, &buffer);
504 derivedT::template log<software_critical>({__FILE__, __LINE__, errno,
"Could not get inode for " + m_shmimName +
". Source process will need to be restarted."});
505 ImageStreamIO_closeIm(&m_imageStream);
508 m_inode = buffer.st_ino;
523 if (derived().m_shutdown)
528 ImageStreamIO_closeIm(&m_imageStream);
532 m_semaphoreNumber = ImageStreamIO_getsemwaitindex(&m_imageStream, m_semaphoreNumber);
534 if (m_semaphoreNumber < 0)
536 derivedT::template log<software_critical>({__FILE__, __LINE__,
"No valid semaphore found for " + m_shmimName +
". Source process will need to be restarted."});
540 derivedT::template log<software_info>({__FILE__, __LINE__,
"got semaphore index " + std::to_string(m_semaphoreNumber) +
" for " + m_shmimName});
542 ImageStreamIO_semflush(&m_imageStream, m_semaphoreNumber);
544 sem_t *sem = m_imageStream.semptr[m_semaphoreNumber];
546 m_dataType = m_imageStream.md[0].datatype;
547 m_typeSize = ImageStreamIO_typesize(m_dataType);
548 m_width = m_imageStream.md[0].size[0];
550 if (m_imageStream.md[0].naxis > 1)
552 m_height = m_imageStream.md[0].size[1];
554 if (m_imageStream.md[0].naxis > 2)
557 m_depth = m_imageStream.md[0].size[2];
571 if (derived().allocate(specificT()) < 0)
573 derivedT::template log<software_error>({__FILE__, __LINE__,
"allocation failed"});
578 size_t snx, sny, snz;
581 if (m_getExistingFirst && !m_restart && derived().shutdown() == 0)
583 if (m_imageStream.md[0].size[2] > 0)
585 curr_image = m_imageStream.md[0].cnt1;
592 atype = m_imageStream.md[0].datatype;
593 snx = m_imageStream.md[0].size[0];
597 sny = m_imageStream.md[0].size[1];
602 sny = m_imageStream.md[0].size[1];
603 snz = m_imageStream.md[0].size[2];
611 if (atype != m_dataType || snx != m_width || sny != m_height || snz != m_depth)
616 char *curr_src = (
char *)m_imageStream.array.raw + curr_image * m_width * m_height * m_typeSize;
618 if (derived().processImage(curr_src, specificT()) < 0)
620 derivedT::template log<software_error>({__FILE__, __LINE__});
630 if (clock_gettime(CLOCK_REALTIME, &ts) < 0)
632 derivedT::template log<software_critical>({__FILE__, __LINE__, errno, 0,
"clock_gettime"});
638 if (sem_timedwait(sem, &ts) == 0)
640 if (m_imageStream.md[0].size[2] > 0)
642 curr_image = m_imageStream.md[0].cnt1;
647 atype = m_imageStream.md[0].datatype;
648 snx = m_imageStream.md[0].size[0];
652 sny = m_imageStream.md[0].size[1];
657 sny = m_imageStream.md[0].size[1];
658 snz = m_imageStream.md[0].size[2];
666 if (atype != m_dataType || snx != m_width || sny != m_height || snz != m_depth)
674 char *curr_src = (
char *)m_imageStream.array.raw + curr_image * m_width * m_height * m_typeSize;
676 if (derived().processImage(curr_src, specificT()) < 0)
678 derivedT::template log<software_error>({__FILE__, __LINE__});
683 if (m_imageStream.md[0].sem <= 0)
692 if (errno != ETIMEDOUT)
694 derivedT::template log<software_error>({__FILE__, __LINE__, errno,
"sem_timedwait"});
701 ImageStreamIO_filename(SM_fname,
sizeof(SM_fname), m_shmimName.c_str());
702 SM_fd = open(SM_fname, O_RDWR);
711 int rv = stat(SM_fname, &buffer);
717 if (buffer.st_ino != m_inode)
729 if (m_semaphoreNumber >= 0)
730 m_imageStream.semReadPID[m_semaphoreNumber] = 0;
731 ImageStreamIO_closeIm(&m_imageStream);
744 ImageStreamIO_closeIm(&m_imageStream);