hmmer-3.3/easel/esl_workqueue.c
/* Function:  esl_workqueue_WorkerUpdate()
 * Synopsis:  Consumer routine.
 * Incept:    MSF, Thu Jun 18 11:51:39 2009
 *
 * Purpose:   The consumer (i.e. Worker) places an object that has
 *            been processed on the producers (i.e. Readers) queue.
 *
 *            If the <in> object is not null, it is placed on the
 *            readers queue.  If the reader is waiting for an object, 
 *            it is signaled it to wake up.
 *
 *            If the worker routine has supplied an <out> pointer,
 *            an object that is ready for processing by a worker,
 *            is placed in <out> so the worker thread can continue.
 *
 * Returns:   <eslOK> on success.
 *
 * Throws:    <eslESYS> if thread synchronization fails somewhere.
 *            <eslEINVAL> if something's wrong with <queue>.
 */
esl_workqueue_WorkerUpdate()
Synopsis:  Consumer routine.

The consumer  places an object that has
been processed on the producers  queue.

If the  object is not null, it is placed on the
readers queue.  If the reader is waiting for an object,
it is signaled it to wake up.

If the worker routine has supplied an  pointer,
an object that is ready for processing by a worker,
is placed in  so the worker thread can continue.

 on success.

 if thread synchronization fails somewhere.
 if something's wrong with .
esl_workqueue_WorkerUpdate () Synopsis : Consumer routine . The consumer places an object that has been processed on the producers queue . If the object is not null it is placed on the readers queue . If the reader is waiting for an object it is signaled it to wake up . If the worker routine has supplied an pointer an object that is ready for processing by a worker is placed in so the worker thread can continue . on success . if thread synchronization fails somewhere . if something ' s wrong with .
int esl_workqueue_WorkerUpdate(ESL_WORK_QUEUE *queue, void *in, void **out)
{
  int cnt;
  int inx;
  int queueSize;
  int status;
  if (queue == NULL)                                ESL_XEXCEPTION(eslEINVAL, "Invalid queue object");
  if (pthread_mutex_lock (&queue->queueMutex) != 0) ESL_XEXCEPTION(eslESYS,   "mutex lock failed");
  queueSize = queue->queueSize;
  if (in != NULL)
    {
      if (queue->readerQueueCnt >= queueSize) ESL_XEXCEPTION(eslEINVAL, "Reader queue overflow");
      inx = (queue->readerQueueHead + queue->readerQueueCnt) % queueSize;
      queue->readerQueue[inx] = in;
      cnt = queue->readerQueueCnt++;
      if (cnt == 0)
	{
	  if (pthread_cond_signal (&queue->readerQueueCond) != 0) ESL_XEXCEPTION(eslESYS, "cond signal failed");
	}
    }
  if (out != NULL)
    {
      if (queue->workerQueueCnt == 0)
	{
	  ++queue->pendingWorkers;
	  while (queue->workerQueueCnt == 0)
	    {
	      if (pthread_cond_wait (&queue->workerQueueCond, &queue->queueMutex) != 0) ESL_XEXCEPTION(eslESYS, "cond wait failed");
	    }
	  --queue->pendingWorkers;
	}
      inx = queue->workerQueueHead;
      *out = queue->workerQueue[inx];
      queue->workerQueue[inx] = NULL;
      queue->workerQueueHead = (queue->workerQueueHead + 1) % queueSize;
      --queue->workerQueueCnt;
    }
  if (pthread_mutex_unlock (&queue->queueMutex) != 0) ESL_XEXCEPTION(eslESYS, "mutex unlock failed");
  return eslOK;
 ERROR:
  if (out) *out = NULL;
  return status;
}
int esl_workqueue_WorkerUpdate ( ESL_WORK_QUEUE * queue , void * in , void * * out ) { int cnt ; int inx ; int queueSize ; int status ; if ( queue == NULL ) ESL_XEXCEPTION ( eslEINVAL , " " ) ; if ( pthread_mutex_lock ( & queue -> queueMutex ) != 0 ) ESL_XEXCEPTION ( eslESYS , " " ) ; queueSize = queue -> queueSize ; if ( in != NULL ) { if ( queue -> readerQueueCnt >= queueSize ) ESL_XEXCEPTION ( eslEINVAL , " " ) ; inx = ( queue -> readerQueueHead + queue -> readerQueueCnt ) % queueSize ; queue -> readerQueue [ inx ] = in ; cnt = queue -> readerQueueCnt ++ ; if ( cnt == 0 ) { if ( pthread_cond_signal ( & queue -> readerQueueCond ) != 0 ) ESL_XEXCEPTION ( eslESYS , " " ) ; } } if ( out != NULL ) { if ( queue -> workerQueueCnt == 0 ) { ++ queue -> pendingWorkers ; while ( queue -> workerQueueCnt == 0 ) { if ( pthread_cond_wait ( & queue -> workerQueueCond , & queue -> queueMutex ) != 0 ) ESL_XEXCEPTION ( eslESYS , " " ) ; } -- queue -> pendingWorkers ; } inx = queue -> workerQueueHead ; * out = queue -> workerQueue [ inx ] ; queue -> workerQueue [ inx ] = NULL ; queue -> workerQueueHead = ( queue -> workerQueueHead + 1 ) % queueSize ; -- queue -> workerQueueCnt ; } if ( pthread_mutex_unlock ( & queue -> queueMutex ) != 0 ) ESL_XEXCEPTION ( eslESYS , " " ) ; return eslOK ; ERROR : if ( out ) * out = NULL ; return status ; }
Function:  esl_workqueue_WorkerUpdate()
 Synopsis:  Consumer routine.
Function : esl_workqueue_WorkerUpdate () Synopsis : Consumer routine .
/* check if the caller is queuing up an item */ /* check to make sure we don't overflow */ /* check if the caller is waiting for a queued item */ /* wait for a processed buffers to be returned */