336 config.add( specificT::configSection() +
".threadPrio",
338 specificT::configSection() +
".threadPrio",
340 specificT::configSection(),
344 "The real-time priority of the shmimMonitor thread." );
346 config.add( specificT::configSection() +
".cpuset",
348 specificT::configSection() +
".cpuset",
350 specificT::configSection(),
354 "The cpuset for the shmimMonitor thread." );
356 config.add( specificT::configSection() +
".shmimName",
358 specificT::configSection() +
".shmimName",
360 specificT::configSection(),
364 "The name of the ImageStreamIO shared memory image. Will be used as /tmp/<shmimName>.im.shm." );
366 config.add( specificT::configSection() +
".getExistingFirst",
368 specificT::configSection() +
".getExistingFirst",
370 specificT::configSection(),
374 "If true an existing image is loaded. If false we wait for a new image." );
377 m_shmimName = derived().configName();
397 m_indiP_shmimName = pcf::IndiProperty( pcf::IndiProperty::Text );
398 m_indiP_shmimName.setDevice( derived().configName() );
399 m_indiP_shmimName.setName( specificT::indiPrefix() +
"_shmimName" );
400 m_indiP_shmimName.setPerm( pcf::IndiProperty::ReadOnly );
401 m_indiP_shmimName.setState( pcf::IndiProperty::Idle );
402 m_indiP_shmimName.add( pcf::IndiElement(
"name" ) );
403 m_indiP_shmimName[
"name"] = m_shmimName;
405 if( derived().registerIndiPropertyNew( m_indiP_shmimName,
nullptr ) < 0 )
407#ifndef SHMIMMONITOR_TEST_NOLOG
408 derivedT::template log<software_error>( { __FILE__, __LINE__ } );
414 m_indiP_frameSize = pcf::IndiProperty( pcf::IndiProperty::Number );
415 m_indiP_frameSize.setDevice( derived().configName() );
416 m_indiP_frameSize.setName( specificT::indiPrefix() +
"_frameSize" );
417 m_indiP_frameSize.setPerm( pcf::IndiProperty::ReadOnly );
418 m_indiP_frameSize.setState( pcf::IndiProperty::Idle );
419 m_indiP_frameSize.add( pcf::IndiElement(
"width" ) );
420 m_indiP_frameSize[
"width"] = 0;
421 m_indiP_frameSize.add( pcf::IndiElement(
"height" ) );
422 m_indiP_frameSize[
"height"] = 0;
424 if( derived().registerIndiPropertyNew( m_indiP_frameSize,
nullptr ) < 0 )
426#ifndef SHMIMMONITOR_TEST_NOLOG
427 derivedT::template log<software_error>( { __FILE__, __LINE__ } );
433 struct sigaction act;
437 act.sa_flags = SA_SIGINFO;
442 if( sigaction( SIGUSR1, &act, 0 ) < 0 )
444 std::string logss =
"Setting handler for SIGUSR1 failed. Errno says: ";
445 logss += strerror( errno );
447 derivedT::template log<software_error>( { __FILE__, __LINE__, errno, 0, logss } );
452 if( derived().threadStart( m_smThread,
458 specificT::configSection(),
460 smThreadStart ) < 0 )
462 derivedT::template log<software_error>( { __FILE__, __LINE__ } );
511 m_smThreadID = syscall( SYS_gettid );
514 while( m_smThreadInit ==
true && derived().shutdown() == 0 )
523 while( derived().shutdown() == 0 )
527 while( ( derived().state() !=
stateCodes::OPERATING || m_shmimName ==
"" ) && !derived().shutdown() &&
533 if( derived().shutdown() )
543 while( !opened && !derived().m_shutdown && !m_restart && derived().state() ==
stateCodes::OPERATING )
549 ImageStreamIO_filename( SM_fname,
sizeof( SM_fname ), m_shmimName.c_str() );
550 SM_fd = open( SM_fname, O_RDWR );
556 derivedT::template log<text_log>(
557 "ImageStream " + m_shmimName +
" not found (yet). Retrying . . .", logPrio::LOG_NOTICE );
569 if( ImageStreamIO_openIm( &m_imageStream, m_shmimName.c_str() ) == 0 )
571 if( m_imageStream.md[0].sem <=
574 ImageStreamIO_closeIm( &m_imageStream );
581 ImageStreamIO_filename( SM_fname,
sizeof( SM_fname ), m_shmimName.c_str() );
584 int rv = stat( SM_fname, &buffer );
588 derivedT::template log<software_critical>(
592 "Could not get inode for " + m_shmimName +
593 ". Source process will need to be restarted." } );
594 ImageStreamIO_closeIm( &m_imageStream );
597 m_inode = buffer.st_ino;
616 if( derived().m_shutdown )
623 ImageStreamIO_closeIm( &m_imageStream );
628 ImageStreamIO_getsemwaitindex( &m_imageStream, m_semaphoreNumber );
630 if( m_semaphoreNumber < 0 )
632 derivedT::template log<software_critical>(
635 "No valid semaphore found for " + m_shmimName +
". Source process will need to be restarted." } );
639 derivedT::template log<software_info>(
642 "got semaphore index " + std::to_string( m_semaphoreNumber ) +
" for " + m_shmimName } );
644 ImageStreamIO_semflush( &m_imageStream, m_semaphoreNumber );
646 sem_t *sem = m_imageStream.semptr[m_semaphoreNumber];
648 m_dataType = m_imageStream.md[0].datatype;
649 m_typeSize = ImageStreamIO_typesize( m_dataType );
650 m_width = m_imageStream.md[0].size[0];
652 if( m_imageStream.md[0].naxis > 1 )
654 m_height = m_imageStream.md[0].size[1];
656 if( m_imageStream.md[0].naxis > 2 )
659 m_depth = m_imageStream.md[0].size[2];
675 if( derived().allocate( specificT() ) < 0 )
677 derivedT::template log<software_error>( { __FILE__, __LINE__,
"allocation failed" } );
682 size_t snx, sny, snz;
685 if( m_getExistingFirst && !m_restart &&
686 derived().shutdown() == 0 )
688 if( m_imageStream.md[0].size[2] > 0 )
690 curr_image = m_imageStream.md[0].cnt1;
697 atype = m_imageStream.md[0].datatype;
698 snx = m_imageStream.md[0].size[0];
702 sny = m_imageStream.md[0].size[1];
707 sny = m_imageStream.md[0].size[1];
708 snz = m_imageStream.md[0].size[2];
716 if( atype != m_dataType || snx != m_width || sny != m_height || snz != m_depth )
721 char *curr_src = (
char *)m_imageStream.array.raw + curr_image * m_width * m_height * m_typeSize;
723 if( derived().processImage( curr_src, specificT() ) < 0 )
725 derivedT::template log<software_error>( { __FILE__, __LINE__ } );
735 if( clock_gettime( CLOCK_REALTIME, &ts ) < 0 )
737 derivedT::template log<software_critical>( { __FILE__, __LINE__, errno, 0,
"clock_gettime" } );
743 if( sem_timedwait( sem, &ts ) == 0 )
745 if( m_imageStream.md[0].size[2] > 0 )
747 curr_image = m_imageStream.md[0].cnt1;
752 atype = m_imageStream.md[0].datatype;
753 snx = m_imageStream.md[0].size[0];
757 sny = m_imageStream.md[0].size[1];
762 sny = m_imageStream.md[0].size[1];
763 snz = m_imageStream.md[0].size[2];
771 if( atype != m_dataType || snx != m_width || sny != m_height || snz != m_depth )
779 char *curr_src = (
char *)m_imageStream.array.raw + curr_image * m_width * m_height * m_typeSize;
781 if( derived().processImage( curr_src, specificT() ) < 0 )
783 derivedT::template log<software_error>( { __FILE__, __LINE__ } );
788 if( m_imageStream.md[0].sem <= 0 )
798 if( errno != ETIMEDOUT )
800 derivedT::template log<software_error>( { __FILE__, __LINE__, errno,
"sem_timedwait" } );
807 ImageStreamIO_filename( SM_fname,
sizeof( SM_fname ), m_shmimName.c_str() );
808 SM_fd = open( SM_fname, O_RDWR );
817 int rv = stat( SM_fname, &buffer );
823 if( buffer.st_ino != m_inode )
835 if( m_semaphoreNumber >= 0 )
836 m_imageStream.semReadPID[m_semaphoreNumber] = 0;
837 ImageStreamIO_closeIm( &m_imageStream );
851 ImageStreamIO_closeIm( &m_imageStream );
858 uint32_t width, uint32_t height, uint32_t depth, uint8_t dtype,
void *initData )
867 ImageStreamIO_filename( SM_fname,
sizeof( SM_fname ), m_shmimName.c_str() );
868 SM_fd = open( SM_fname, O_RDWR );
873 if( ImageStreamIO_openIm( &m_imageStream, m_shmimName.c_str() ) != IMAGESTREAMIO_SUCCESS )
875 return derivedT::template log<software_error, -1>( { __FILE__, __LINE__,
"error from ImageStreamIO" } );
878 if( ImageStreamIO_destroyIm( &m_imageStream ) != IMAGESTREAMIO_SUCCESS )
880 return derivedT::template log<software_error, -1>( { __FILE__, __LINE__,
"error from ImageStreamIO" } );
884 uint32_t imsize[3] = { 0, 0, 0 };
890 std::cerr <<
"Creating: " << m_shmimName <<
" " << width <<
" " << height <<
" " << depth <<
"\n";
892 if( ImageStreamIO_createIm_gpu( &imageStream,
901 CIRCULAR_BUFFER | ZAXIS_TEMPORAL,
902 0 ) != IMAGESTREAMIO_SUCCESS )
904 return derivedT::template log<software_error, -1>( { __FILE__, __LINE__,
"error from ImageStreamIO" } );
907 if( initData !=
nullptr )
909 memcpy( imageStream.array.raw, initData, width * height * ImageStreamIO_typesize( dtype ) );
912 imageStream.md->cnt1 = depth - 1;
914 if( ImageStreamIO_closeIm( &imageStream ) != IMAGESTREAMIO_SUCCESS )
916 return derivedT::template log<software_error, -1>( { __FILE__, __LINE__,
"error from ImageStreamIO" } );