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