evq_queue.c

Go to the documentation of this file.
00001 #include "common/evq_queue.h"
00002 
00003 #include "common/threading.h"
00004 
00005 #include <stdio.h>
00006 #include <unistd.h>
00007 #include <assert.h>
00008 
00009 void queue_init(Queue* q)
00010 {
00011   q->head = q->tail = NULL;
00012   mutex_init(&q->mutex);
00013   cond_init(&q->cond);
00014   q->running = 1;
00015 }
00016 
00017 void queue_put(Queue* q, QueueItem* item)
00018 {
00019   mutex_lock(&q->mutex);
00020 
00021   if (q->running) {
00022     if (q->tail) {
00023       q->tail->next = item;
00024       q->tail = item;
00025     } else {
00026       q->head = q->tail = item;
00027     }
00028     item->next = NULL;
00029     cond_signal(&q->cond); // always succeeds
00030   }
00031 
00032   mutex_unlock(&q->mutex);
00033 }
00034 
00035 // Removes the first item of "q", which must exist.
00036 static void unshift(Queue* q) {
00037   QueueItem* shifted;
00038   shifted = q->head;
00039   assert(shifted && "unshift on empty queue");
00040   if (shifted->next) {
00041     q->head = shifted->next;
00042     if (!q->head->next)
00043       q->tail = q->head;
00044   } else {
00045     q->head = q->tail = NULL;
00046   }
00047 }
00048 
00049 void queue_remove(Queue* q, QueueItem* item)
00050 {
00051   mutex_lock(&q->mutex);
00052 
00053   if (q->running && q->head) {
00054     if (q->head == item) {
00055       unshift(q);
00056     } else {
00057       QueueItem* p = q->head;
00058       while (p->next) {
00059         if (p->next == item) {
00060           p->next = p->next->next;
00061           if (!p->next) q->tail = p;
00062           break;
00063         }
00064         p = p->next;
00065       }
00066     }
00067   }
00068 
00069   mutex_unlock(&q->mutex);
00070 }
00071 
00072 QueueItem* queue_get(Queue* q)
00073 {
00074   QueueItem* item = NULL;
00075 
00076   mutex_lock(&q->mutex);
00077 
00078   while (q->running) {
00079     if (q->head) {
00080       item = q->head;
00081       unshift(q);
00082       break;
00083     } else {
00084       cond_wait(&q->cond, &q->mutex); // never returns an error
00085       // Note that due to the existence of queue_remove, it is possible that we get a signal without there actually being any items in the queue any longer.
00086     }
00087   }
00088 
00089   mutex_unlock(&q->mutex);
00090 
00091   return item;
00092 }
00093 
00094 // Set to stopped and notify any and all waiters that no further
00095 // waiting on the condition is allowed any longer, and that there will
00096 // be no more items in the queue.
00097 void queue_stop(Queue* q)
00098 {
00099   mutex_lock(&q->mutex);
00100 
00101   q->running = 0;
00102   cond_broadcast(&q->cond); // always succeeds
00103 
00104   mutex_unlock(&q->mutex);
00105 }
00106 
00107 void queue_close(Queue* q)
00108 {
00109   // On Linux, there are no resources to free, but this might not be the case on other platforms. There is little to do if this fails since we do want "close" to always succeed. Note that there may not be threads waiting on the condition when we make this call.
00110   cond_destroy(&q->cond);
00111 
00112   // On Linux, there are no resources to free, but this might not be the case on other platforms. There is little to do if this fails since we do want "close" to always succeed. Note that the mutex may not be locked when we make this call.
00113   mutex_destroy(&q->mutex);
00114 }
00115 
00116 /**
00117 
00118 evq_queue.c
00119 
00120 Copyright 2009 Helsinki Institute for Information Technology (HIIT)
00121 and the authors. All rights reserved.
00122 
00123 Authors: Tero Hasu <tero.hasu@hut.fi>
00124 
00125 Permission is hereby granted, free of charge, to any person
00126 obtaining a copy of this software and associated documentation files
00127 (the "Software"), to deal in the Software without restriction,
00128 including without limitation the rights to use, copy, modify, merge,
00129 publish, distribute, sublicense, and/or sell copies of the Software,
00130 and to permit persons to whom the Software is furnished to do so,
00131 subject to the following conditions:
00132 
00133 The above copyright notice and this permission notice shall be
00134 included in all copies or substantial portions of the Software.
00135 
00136 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00137 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00138 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00139 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
00140 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
00141 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00142 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
00143 SOFTWARE.
00144 
00145  **/

ContextLogger2—ContextLogger2 Logger Daemon Internals—Generated on Mon May 2 13:49:52 2011 by Doxygen 1.6.1