queue.c

Go to the documentation of this file.
00001 
00006 /* $Id: queue.c,v 1.3 2004/09/29 20:47:31 seymour Exp $ */
00007 /* $UTK_Copyright: $ */
00008 
00009 #include "queue.h"
00010 
00013 #define DESTROY_QUEUE()     { if(q->mutex) free(q->mutex); \
00014     if(q->notFull) free(q->notFull); \
00015     if(q->notEmpty) free(q->notEmpty); \
00016     free(q); }
00017 
00024 QUEUE *
00025 new_queue()
00026 {
00027   QUEUE *q;
00028 
00029   q = (QUEUE *) malloc(sizeof(QUEUE));
00030 
00031   if (!q)
00032     return NULL;
00033 
00034   q->head = q->tail = NULL;
00035 
00036   q->mutex = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
00037   q->notFull = (pthread_cond_t *) malloc(sizeof(pthread_cond_t));
00038   q->notEmpty = (pthread_cond_t *) malloc(sizeof(pthread_cond_t));
00039 
00040   if (!q->mutex || !q->notFull || !q->notEmpty) {
00041     DESTROY_QUEUE();
00042     return NULL;
00043   }
00044 
00045   if (pthread_mutex_init(q->mutex, NULL)) {
00046     DESTROY_QUEUE();
00047     return NULL;
00048   }
00049 
00050   if (pthread_cond_init(q->notFull, NULL)) {
00051     pthread_mutex_destroy(q->mutex);
00052     DESTROY_QUEUE();
00053     return NULL;
00054   }
00055 
00056   if (pthread_cond_init(q->notEmpty, NULL)) {
00057     pthread_mutex_destroy(q->mutex);
00058     pthread_cond_destroy(q->notFull);
00059     DESTROY_QUEUE();
00060     return NULL;
00061   }
00062 
00063   return q;
00064 }
00065 
00074 int 
00075 destroy_queue(QUEUE * q)
00076 {
00077   pthread_mutex_destroy(q->mutex);
00078   pthread_cond_destroy(q->notFull);
00079   pthread_cond_destroy(q->notEmpty);
00080 
00081   while (dequeue(q))        /* spin */
00082     ;
00083   DESTROY_QUEUE();
00084   return 0;
00085 }
00086 
00096 int 
00097 enqueue(QUEUE * q, void *val)
00098 {
00099   Q_ITEM *item;
00100 
00101   item = (Q_ITEM *) malloc(sizeof(Q_ITEM));
00102 
00103   if (!item)
00104     return -1;
00105 
00106   item->val = val;
00107   item->next = q->head;
00108   item->prev = NULL;
00109 
00110   if (q->head)
00111     q->head->prev = item;
00112 
00113   q->head = item;
00114   if (!q->tail)
00115     q->tail = item;
00116 
00117   return 0;
00118 }
00119 
00128 void *
00129 dequeue(QUEUE * q)
00130 {
00131   void *retval;
00132   Q_ITEM *tail;
00133 
00134   if (!q->tail)
00135     return NULL;
00136 
00137   tail = q->tail;
00138 
00139   if (q->tail->prev)
00140     q->tail->prev->next = NULL;
00141   q->tail = q->tail->prev;
00142 
00143   if (!q->tail)
00144     q->head = NULL;
00145 
00146   retval = tail->val;
00147   free(tail);
00148 
00149   return retval;
00150 }