mksh/mksh.logging/src.1mai/atrshmlog_internal.c
int atrshmlog_read(const int i_index_buffer,
           void *o_target,
           int *o_target_length)
{
  int result = -1;

  if(!ATRSHMLOGLOGGING)
    return result;

  --result;
     
  if (i_index_buffer < 0)
    return result;

  --result;
  
  atr_shm_log_area_t *i_shm = ATRSHMLOGGETAREA;
  
  if (i_shm->shmid != atrshmlog_shmid())
    return result;

  --result;
  
  if (i_shm->safeguard != SAFEGUARDVALUE)
    return result;

  --result;
  
  if (ATRSHMLOGCUTOFFLOWBYTE(i_shm->count) <= i_index_buffer)
    return result;

  --result;

  if (i_shm->version != ATRSHMLOGVERSION)
    return result;
  
  /* ok. we can now do the transfer */

  atr_shm_log_buffer_t* b = &(i_shm->logbuffers[i_index_buffer]);

  int lock_mutex_result ;

  int unlock_mutex_result;
    
  pthread_mutex_t* m = &(b->lock_mutex);

  volatile int state;
    
  --result ;

  state = ATRSHMLOGCUTOFFLOWBYTE(b->state);
    
  if (!(state == atr_shm_log_writeable
    || state == atr_shm_log_write_halffull
    || state == atr_shm_log_full))
    return result;

  do {
    lock_mutex_result = pthread_mutex_lock(m);
  } while (lock_mutex_result != 0);

  /* from now on we have to do an unlock */
  state = b->state;

  /* we block all concurrent writers */
  b->state = atr_shm_log_illegal;
  
  int size = b->size;
    
  --result;

  if (size < 0)
    {
      goto ende;
    }

  --result;
    
  if (size > ATRSHMLOGBUFFER_INFOSIZE)
    {
      goto ende;
    }

  --result ;

  if (!(state == atr_shm_log_writeable
    || state == atr_shm_log_write_halffull
    || state == atr_shm_log_full))
    {
      /* restore state */
      b->state = state;
      goto ende;
    }

  /* we have to check the slots now  */


 slotcheck:
  for (int i = 0 ; i < ATRSHMLOGSLOTCOUNT; i++)
    if (b->slots[i] != 0)
      {
    usleep(1);
    goto slotcheck;
      }

  /* ok. we are clear to go to copy */

  /* is the length ok for copy */ 

  if (size > 0)
    {
      /* we have to do the copy now */

      (void)memcpy(o_target, &(b->info[0]), size);
    }

  *o_target_length = size;

  b->size = 0;
  
  b->state = atr_shm_log_writeable;
      
  result = 0;

 ende:
  do {
    unlock_mutex_result = pthread_mutex_unlock(m);
  } while (unlock_mutex_result != 0);

  return result;
}
/* we read a buffer and write it to a local memory area
 * we can read half full, full and writeable buffers
 * the latter is needed for the cleanup after finish of the 
 * buffers so far not cleared and only partly full
 * pthread version
 *  this is done in a safe way. so we can do this in parallel
 * to running writers.
 * and we need to do it. if all buffers are full the writers have 
 * to loop forever. so we have to use the mt safe way here
 * thats a bit a blockade of the system, but if the number of
 * buffers is sufficient we dont disturb the writers much..
 * they check from outside of the mutex.
 * so we can simply lock, switch the flag to dont disturb me mode
 * and clenaup the buffer.
 * anything else is up to the writer
 * process. so try to handle the data then as fast as you can.
 * see for a simple reader the
 * atrshmlogreader.c
 */
we read a buffer and write it to a local memory area
we can read half full, full and writeable buffers
the latter is needed for the cleanup after finish of the
buffers so far not cleared and only partly full
pthread version
this is done in a safe way. so we can do this in parallel
to running writers.
and we need to do it. if all buffers are full the writers have
to loop forever. so we have to use the mt safe way here
thats a bit a blockade of the system, but if the number of
buffers is sufficient we dont disturb the writers much
they check from outside of the mutex.
so we can simply lock, switch the flag to dont disturb me mode
and clenaup the buffer.
anything else is up to the writer
process. so try to handle the data then as fast as you can.
see for a simple reader the
atrshmlogreader.c
we read a buffer and write it to a local memory area we can read half full full and writeable buffers the latter is needed for the cleanup after finish of the buffers so far not cleared and only partly full pthread version this is done in a safe way . so we can do this in parallel to running writers . and we need to do it . if all buffers are full the writers have to loop forever . so we have to use the mt safe way here thats a bit a blockade of the system but if the number of buffers is sufficient we dont disturb the writers much they check from outside of the mutex . so we can simply lock switch the flag to dont disturb me mode and clenaup the buffer . anything else is up to the writer process . so try to handle the data then as fast as you can . see for a simple reader the atrshmlogreader . c
int atrshmlog_read(const int i_index_buffer,
           void *o_target,
           int *o_target_length)
{
  int result = -1;
  if(!ATRSHMLOGLOGGING)
    return result;
  --result;
  if (i_index_buffer < 0)
    return result;
  --result;
  atr_shm_log_area_t *i_shm = ATRSHMLOGGETAREA;
  if (i_shm->shmid != atrshmlog_shmid())
    return result;
  --result;
  if (i_shm->safeguard != SAFEGUARDVALUE)
    return result;
  --result;
  if (ATRSHMLOGCUTOFFLOWBYTE(i_shm->count) <= i_index_buffer)
    return result;
  --result;
  if (i_shm->version != ATRSHMLOGVERSION)
    return result;
  atr_shm_log_buffer_t* b = &(i_shm->logbuffers[i_index_buffer]);
  int lock_mutex_result ;
  int unlock_mutex_result;
  pthread_mutex_t* m = &(b->lock_mutex);
  volatile int state;
  --result ;
  state = ATRSHMLOGCUTOFFLOWBYTE(b->state);
  if (!(state == atr_shm_log_writeable
    || state == atr_shm_log_write_halffull
    || state == atr_shm_log_full))
    return result;
  do {
    lock_mutex_result = pthread_mutex_lock(m);
  } while (lock_mutex_result != 0);
  state = b->state;
  b->state = atr_shm_log_illegal;
  int size = b->size;
  --result;
  if (size < 0)
    {
      goto ende;
    }
  --result;
  if (size > ATRSHMLOGBUFFER_INFOSIZE)
    {
      goto ende;
    }
  --result ;
  if (!(state == atr_shm_log_writeable
    || state == atr_shm_log_write_halffull
    || state == atr_shm_log_full))
    {
      b->state = state;
      goto ende;
    }
 slotcheck:
  for (int i = 0 ; i < ATRSHMLOGSLOTCOUNT; i++)
    if (b->slots[i] != 0)
      {
    usleep(1);
    goto slotcheck;
      }
  if (size > 0)
    {
      (void)memcpy(o_target, &(b->info[0]), size);
    }
  *o_target_length = size;
  b->size = 0;
  b->state = atr_shm_log_writeable;
  result = 0;
 ende:
  do {
    unlock_mutex_result = pthread_mutex_unlock(m);
  } while (unlock_mutex_result != 0);
  return result;
}
int atrshmlog_read ( const int i_index_buffer , void * o_target , int * o_target_length ) { int result = -1 ; if ( ! ATRSHMLOGLOGGING ) return result ; -- result ; if ( i_index_buffer < 0 ) return result ; -- result ; atr_shm_log_area_t * i_shm = ATRSHMLOGGETAREA ; if ( i_shm -> shmid != atrshmlog_shmid ( ) ) return result ; -- result ; if ( i_shm -> safeguard != SAFEGUARDVALUE ) return result ; -- result ; if ( ATRSHMLOGCUTOFFLOWBYTE ( i_shm -> count ) <= i_index_buffer ) return result ; -- result ; if ( i_shm -> version != ATRSHMLOGVERSION ) return result ; atr_shm_log_buffer_t * b = & ( i_shm -> logbuffers [ i_index_buffer ] ) ; int lock_mutex_result ; int unlock_mutex_result ; pthread_mutex_t * m = & ( b -> lock_mutex ) ; volatile int state ; -- result ; state = ATRSHMLOGCUTOFFLOWBYTE ( b -> state ) ; if ( ! ( state == atr_shm_log_writeable || state == atr_shm_log_write_halffull || state == atr_shm_log_full ) ) return result ; do { lock_mutex_result = pthread_mutex_lock ( m ) ; } while ( lock_mutex_result != 0 ) ; state = b -> state ; b -> state = atr_shm_log_illegal ; int size = b -> size ; -- result ; if ( size < 0 ) { goto ende ; } -- result ; if ( size > ATRSHMLOGBUFFER_INFOSIZE ) { goto ende ; } -- result ; if ( ! ( state == atr_shm_log_writeable || state == atr_shm_log_write_halffull || state == atr_shm_log_full ) ) { b -> state = state ; goto ende ; } slotcheck : for ( int i = 0 ; i < ATRSHMLOGSLOTCOUNT ; i ++ ) if ( b -> slots [ i ] != 0 ) { usleep ( 1 ) ; goto slotcheck ; } if ( size > 0 ) { ( void ) memcpy ( o_target , & ( b -> info [ 0 ] ) , size ) ; } * o_target_length = size ; b -> size = 0 ; b -> state = atr_shm_log_writeable ; result = 0 ; ende : do { unlock_mutex_result = pthread_mutex_unlock ( m ) ; } while ( unlock_mutex_result != 0 ) ; return result ; }
we read a buffer and write it to a local memory area
 we can read half full, full and writeable buffers
 the latter is needed for the cleanup after finish of the
 buffers so far not cleared and only partly full
 pthread version
  this is done in a safe way.
we read a buffer and write it to a local memory area we can read half full full and writeable buffers the latter is needed for the cleanup after finish of the buffers so far not cleared and only partly full pthread version this is done in a safe way .
/* ok. we can now do the transfer */ /* from now on we have to do an unlock */ /* we block all concurrent writers */ /* restore state */ /* we have to check the slots now  */ /* ok. we are clear to go to copy */ /* is the length ok for copy */ /* we have to do the copy now */