338 config.add( specificT::configSection() +
".threadPrio",
340 specificT::configSection() +
".threadPrio",
342 specificT::configSection(),
346 "The real-time priority of the shmimMonitor thread." );
348 config.add( specificT::configSection() +
".cpuset",
350 specificT::configSection() +
".cpuset",
352 specificT::configSection(),
356 "The cpuset for the shmimMonitor thread." );
358 config.add( specificT::configSection() +
".shmimName",
360 specificT::configSection() +
".shmimName",
362 specificT::configSection(),
366 "The name of the ImageStreamIO shared memory image. Will be used as /tmp/<shmimName>.im.shm." );
368 config.add( specificT::configSection() +
".getExistingFirst",
370 specificT::configSection() +
".getExistingFirst",
372 specificT::configSection(),
376 "If true an existing image is loaded. If false we wait for a new image." );
379 m_shmimName = derived().configName();
399 m_indiP_shmimName = pcf::IndiProperty( pcf::IndiProperty::Text );
400 m_indiP_shmimName.setDevice( derived().configName() );
401 m_indiP_shmimName.setName( specificT::indiPrefix() +
"_shmimName" );
402 m_indiP_shmimName.setPerm( pcf::IndiProperty::ReadOnly );
403 m_indiP_shmimName.setState( pcf::IndiProperty::Idle );
404 m_indiP_shmimName.add( pcf::IndiElement(
"name" ) );
405 m_indiP_shmimName[
"name"] = m_shmimName;
407 if( derived().registerIndiPropertyNew( m_indiP_shmimName,
nullptr ) < 0 )
409#ifndef SHMIMMONITOR_TEST_NOLOG
410 derivedT::template log<software_error>( { __FILE__, __LINE__ } );
416 m_indiP_frameSize = pcf::IndiProperty( pcf::IndiProperty::Number );
417 m_indiP_frameSize.setDevice( derived().configName() );
418 m_indiP_frameSize.setName( specificT::indiPrefix() +
"_frameSize" );
419 m_indiP_frameSize.setPerm( pcf::IndiProperty::ReadOnly );
420 m_indiP_frameSize.setState( pcf::IndiProperty::Idle );
421 m_indiP_frameSize.add( pcf::IndiElement(
"width" ) );
422 m_indiP_frameSize[
"width"] = 0;
423 m_indiP_frameSize.add( pcf::IndiElement(
"height" ) );
424 m_indiP_frameSize[
"height"] = 0;
426 if( derived().registerIndiPropertyNew( m_indiP_frameSize,
nullptr ) < 0 )
428#ifndef SHMIMMONITOR_TEST_NOLOG
429 derivedT::template log<software_error>( { __FILE__, __LINE__ } );
435 struct sigaction act;
439 act.sa_flags = SA_SIGINFO;
444 if( sigaction( SIGUSR1, &act, 0 ) < 0 )
446 std::string logss =
"Setting handler for SIGUSR1 failed. Errno says: ";
447 logss += strerror( errno );
449 derivedT::template log<software_error>( { __FILE__, __LINE__, errno, 0, logss } );
454 if( derived().threadStart( m_smThread,
460 specificT::configSection(),
462 smThreadStart ) < 0 )
464 derivedT::template log<software_error>( { __FILE__, __LINE__ } );
513 m_smThreadID = syscall( SYS_gettid );
516 while( m_smThreadInit ==
true && derived().shutdown() == 0 )
525 std::cerr << m_shmimName <<
" smThreadExec\n";
527 while( derived().shutdown() == 0 )
531 while( ( derived().state() != m_targetState || m_shmimName ==
"" ) && !derived().shutdown() && !m_restart )
536 if( derived().shutdown() )
548 while( !opened && !derived().m_shutdown && !m_restart && derived().state() == m_targetState )
554 ImageStreamIO_filename( SM_fname,
sizeof( SM_fname ), m_shmimName.c_str() );
555 SM_fd = open( SM_fname, O_RDWR );
561 derivedT::template log<text_log>(
562 "ImageStream " + m_shmimName +
" not found (yet). Retrying . . .", logPrio::LOG_NOTICE );
574 if( ImageStreamIO_openIm( &m_imageStream, m_shmimName.c_str() ) == 0 )
576 if( m_imageStream.md[0].sem < SEMAPHORE_MAXVAL )
578 ImageStreamIO_closeIm( &m_imageStream );
585 ImageStreamIO_filename( SM_fname,
sizeof( SM_fname ), m_shmimName.c_str() );
588 int rv = stat( SM_fname, &buffer );
592 derivedT::template log<software_critical>(
596 "Could not get inode for " + m_shmimName +
597 ". Source process will need to be restarted." } );
598 ImageStreamIO_closeIm( &m_imageStream );
602 m_inode = buffer.st_ino;
616 if( derived().state() != m_targetState )
621 if( derived().m_shutdown )
628 ImageStreamIO_closeIm( &m_imageStream );
633 ImageStreamIO_getsemwaitindex( &m_imageStream, m_semaphoreNumber );
635 if( m_semaphoreNumber < 0 )
637 derivedT::template log<software_critical>(
640 "No valid semaphore found for " + m_shmimName +
". Source process will need to be restarted." } );
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;
686 if( m_getExistingFirst && !m_restart && 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__ } );
730 while( derived().shutdown() == 0 && !m_restart && derived().state() == m_targetState )
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;
754 atype = m_imageStream.md[0].datatype;
755 snx = m_imageStream.md[0].size[0];
759 sny = m_imageStream.md[0].size[1];
764 sny = m_imageStream.md[0].size[1];
765 snz = m_imageStream.md[0].size[2];
773 if( atype != m_dataType || snx != m_width || sny != m_height || snz != m_depth )
778 if( derived().shutdown() != 0 || m_restart || derived().state() != m_targetState )
783 char *curr_src = (
char *)m_imageStream.array.raw + curr_image * m_width * m_height * m_typeSize;
785 if( derived().processImage( curr_src, specificT() ) < 0 )
787 derivedT::template log<software_error>( { __FILE__, __LINE__ } );
792 if( m_imageStream.md[0].sem <= 0 )
802 if( errno != ETIMEDOUT )
804 derivedT::template log<software_error>( { __FILE__, __LINE__, errno,
"sem_timedwait" } );
811 ImageStreamIO_filename( SM_fname,
sizeof( SM_fname ), m_shmimName.c_str() );
812 SM_fd = open( SM_fname, O_RDWR );
821 int rv = stat( SM_fname, &buffer );
827 if( buffer.st_ino != m_inode )
839 if( m_semaphoreNumber >= 0 )
840 m_imageStream.semReadPID[m_semaphoreNumber] = 0;
841 ImageStreamIO_closeIm( &m_imageStream );
855 ImageStreamIO_closeIm( &m_imageStream );
862 uint32_t width, uint32_t height, uint32_t depth, uint8_t dtype,
void *initData )
871 ImageStreamIO_filename( SM_fname,
sizeof( SM_fname ), m_shmimName.c_str() );
872 SM_fd = open( SM_fname, O_RDWR );
877 if( ImageStreamIO_openIm( &m_imageStream, m_shmimName.c_str() ) != IMAGESTREAMIO_SUCCESS )
879 return derivedT::template log<software_error, -1>( { __FILE__, __LINE__,
"error from ImageStreamIO" } );
882 if( ImageStreamIO_destroyIm( &m_imageStream ) != IMAGESTREAMIO_SUCCESS )
884 return derivedT::template log<software_error, -1>( { __FILE__, __LINE__,
"error from ImageStreamIO" } );
888 uint32_t imsize[3] = { 0, 0, 0 };
894 std::cerr <<
"Creating: " << m_shmimName <<
" " << width <<
" " << height <<
" " << depth <<
"\n";
896 if( ImageStreamIO_createIm_gpu( &imageStream,
905 CIRCULAR_BUFFER | ZAXIS_TEMPORAL,
906 0 ) != IMAGESTREAMIO_SUCCESS )
908 return derivedT::template log<software_error, -1>( { __FILE__, __LINE__,
"error from ImageStreamIO" } );
911 if( initData !=
nullptr )
913 memcpy( imageStream.array.raw, initData, width * height * ImageStreamIO_typesize( dtype ) );
916 imageStream.md->cnt1 = depth - 1;
918 if( ImageStreamIO_closeIm( &imageStream ) != IMAGESTREAMIO_SUCCESS )
920 return derivedT::template log<software_error, -1>( { __FILE__, __LINE__,
"error from ImageStreamIO" } );