Simple tools for multi threading / objects in plain C Snapshot
Classes | Typedefs | Functions
TQUEUE

Implements a thread safe queue with maximum limit of requess. More...

Classes

struct  tagTQUEUE

Typedefs

typedef struct tagTQUEUE TQUEUE

Functions

int TQUEUE_init (TQUEUE *queue, size_t max_count)
 create new queue
int TQUEUE_free (TQUEUE *queue)
 destroy queue
int TQUEUE_push_block_on_queue_full (TQUEUE *queue, void *entry)
 add new entry to queue, block if maximum queue limit has been reached
int TQUEUE_push_fail_on_queue_full (TQUEUE *queue, void *entry)
 add new entry to queue, fail if maximum queue limit has been reached
int TQUEUE_push_exit_message (TQUEUE *queue)
 push out of order exit message (null message at top of queue)
void * TQUEUE_pop (TQUEUE *queue)
 pop queue, block if empty
int TQUEUE_pop_non_blocking (TQUEUE *queue, void **rret)
 pop queue, return error if empty. Does not block if queue is empty.

Detailed Description

Implements a thread safe queue with maximum limit of requess.


Typedef Documentation

typedef struct tagTQUEUE TQUEUE

Function Documentation

int TQUEUE_free ( TQUEUE queue)

destroy queue

Definition at line 27 of file tqueue.c.

{
  pthread_cond_destroy( &queue->cond_empty );
  pthread_cond_destroy( &queue->cond_max );
  pthread_mutex_destroy( &queue->mutex );
  return 0;
}
int TQUEUE_init ( TQUEUE queue,
size_t  max_count 
)

create new queue

Definition at line 14 of file tqueue.c.

{
  pthread_mutex_init( &queue->mutex, 0 );
  pthread_cond_init( &queue->cond_empty, 0 );
  pthread_cond_init( &queue->cond_max, 0 );

  DLIST_init( &queue->dlist );

  queue->max_count = max_count;  
  queue->waiting_empty = 0;
  return 0;
}
void* TQUEUE_pop ( TQUEUE queue)

pop queue, block if empty

Definition at line 173 of file tqueue.c.

{
    TQUEUE_Entry  *entry;
    void *ret  = 0;
    int rt;

    if (pthread_mutex_lock(&queue->mutex)) {
      perror("pthread_mutex_lock failed");
      return 0;
    }

    if (DLIST_isempty( &queue->dlist ) ) {
         queue->waiting_empty ++;
         rt = pthread_cond_wait( &queue->cond_empty, &queue->mutex );
         if (rt) {
           perror("pthread_cond_wait failed");
         }
         queue->waiting_empty --;
    }

    entry = (TQUEUE_Entry  *) DLIST_pop_back( &queue->dlist );
    if (entry) {
      ret = entry->entry;
      free(entry);
    }


    if (queue->max_count != 0 &&
        DLIST_size( &queue->dlist ) == (queue->max_count-1)) {
        rt = pthread_cond_signal( &queue->cond_max );
        if (rt) {
           perror("pthread_cond_signal failed");
        }
    } 

    pthread_mutex_unlock( &queue->mutex );

    return ret;
}
int TQUEUE_pop_non_blocking ( TQUEUE queue,
void **  rret 
)

pop queue, return error if empty. Does not block if queue is empty.

Definition at line 147 of file tqueue.c.

{
    TQUEUE_Entry  *entry = 0;
    void *ret = 0;

    if (pthread_mutex_lock(&queue->mutex)) {
      perror("pthread_mutex_lock failed");
      return 0;
    }
    if (!DLIST_isempty( &queue->dlist)) {
        entry = (TQUEUE_Entry  *) DLIST_pop_back( &queue->dlist );
    }
    pthread_mutex_unlock( &queue->mutex );

    if (entry) {
      ret = entry->entry;
      free(entry);
    }

    if (ret != 0) {
      return 0;
    }
    *rret = ret;
    return -1;
}
int TQUEUE_push_block_on_queue_full ( TQUEUE queue,
void *  entry 
)

add new entry to queue, block if maximum queue limit has been reached

Definition at line 77 of file tqueue.c.

{
  int r;

  if ((r = pthread_mutex_lock(&queue->mutex)) != 0 ) {
    errorp(r,"pthread_mutex_lock failed");
    return -1;
  }
  int rt = 0;

  if (queue->max_count != 0 &&
      DLIST_size( &queue->dlist ) >= queue->max_count) {
        
      if ((r = pthread_cond_wait( &queue->cond_max, &queue->mutex )) != 0 ) {
        errorp(r,"pthread_cond_wait failed");
      }
  }
  
  if (!push_entry( &queue->dlist, entry )) {
    if (queue->waiting_empty > 0) {
      if ((r = pthread_cond_signal( &queue->cond_empty )) != 0)  {
        errorp(r, "pthread_cond_signal failed");
      }
    }
  } else {
    rt = -1;
  }

  if ((r = pthread_mutex_unlock( &queue->mutex )) != 0) {
    errorp(r, "pthread_mutex_unlock fails");
    return -1;
  }
  return rt;

}
int TQUEUE_push_exit_message ( TQUEUE queue)

push out of order exit message (null message at top of queue)

Definition at line 46 of file tqueue.c.

{
  int rt = 0,r;
  TQUEUE_Entry *entry; 

  if ((r = pthread_mutex_lock(&queue->mutex)) != 0) {
    errorp(r, "pthread_mutex_lock failed");
    return -1;
  }
  entry = (TQUEUE_Entry *) malloc( sizeof(TQUEUE_Entry) );
  entry->entry = 0;
  
  if (entry) {
    DLIST_push_back( &queue->dlist, (DLIST_entry *) entry );
    if (queue->waiting_empty > 0) {
      if ((r = pthread_cond_signal( &queue->cond_empty )) != 0) {
        errorp(r, "pthread_cond_signal failed");
      }
    }
  } else {
    rt = -1;
  }

  if ((r = pthread_mutex_unlock( &queue->mutex )) != 0) {
    errorp( r, "pthread_mutex_unlock failed");
    return -1;
  }
   
  return rt;
}
int TQUEUE_push_fail_on_queue_full ( TQUEUE queue,
void *  entry 
)

add new entry to queue, fail if maximum queue limit has been reached

Definition at line 113 of file tqueue.c.

{
  int rt = 0, r;

  if ((r = pthread_mutex_lock(&queue->mutex)) != 0) {
    errorp(r, "pthread_mutex_lock failed");
    return -1;
  }

  if (queue->max_count != 0 &&
    DLIST_size( &queue->dlist ) >= queue->max_count) {
    rt = -1;
  } else {
  
    if (! push_entry( &queue->dlist, entry )) {
      if (queue->waiting_empty > 0) {
         rt = pthread_cond_signal( &queue->cond_empty );
         if (rt) {
           errorp(rt, "pthread_cond_signal failed");
         } 
      }
    } else {
      rt = -1;
    }
  }
  if ((r = pthread_mutex_unlock( &queue->mutex )) != 0) {
    errorp(r, "pthread_mutex_unlock failed");
    return -1;
  }

  return rt;
}