On 05/21/2015 06:42 PM, Jiri Denemark wrote: > Our usage of pthread conditions does not allow a single thread to wait > for several events from different sources. This is because the condition > is bound to the source of the event. We can invert the usage by giving > each thread its own condition and providing APIs for registering this > thread condition with several sources. Each of the sources can then > signal the thread condition. > > Thread queues also support several threads to be registered with a > single event source, which can either wakeup all waiting threads or just > the first one. > > Signed-off-by: Jiri Denemark <jdenemar@xxxxxxxxxx> > --- > po/POTFILES.in | 1 + > src/Makefile.am | 2 + > src/libvirt_private.syms | 15 ++ > src/util/virthreadqueue.c | 343 ++++++++++++++++++++++++++++++++++++++++++++++ > src/util/virthreadqueue.h | 54 ++++++++ > 5 files changed, 415 insertions(+) > create mode 100644 src/util/virthreadqueue.c > create mode 100644 src/util/virthreadqueue.h > Ran the series through Coverity and came back with this gem > + > +void > +virThreadQueueFree(virThreadQueuePtr queue) > +{ > + if (!queue) > + return; > + > + while (queue->head) > + virThreadQueueRemove(queue, queue->head); (3) Event cond_true: Condition "queue->head", taking true branch (6) Event loop_begin: Jumped back to beginning of loop (7) Event cond_true: Condition "queue->head", taking true branch 283 while (queue->head) (4) Event freed_arg: "virThreadQueueRemove" frees "queue->head". [details] (5) Event loop: Jumping back to the beginning of the loop (8) Event deref_arg: Calling "virThreadQueueRemove" dereferences freed pointer "queue->head". [details] 284 virThreadQueueRemove(queue, queue->head); > + VIR_FREE(queue); > +} > + > + Where the link to [details] has: 230 static void 231 virThreadQueueRemove(virThreadQueuePtr queue, 232 virThreadQueueItemPtr item) 233 { (1) Event cond_true: Condition "item->prev", taking true branch (1) Event deref_parm: Directly dereferencing parameter "item". Also see events: [freed_arg] 234 if (item->prev) (2) Event if_fallthrough: Falling through to end of if statement 235 item->prev->next = item->next; 236 else (3) Event if_end: End of if statement 237 queue->head = item->next; 238 (4) Event cond_true: Condition "item->next", taking true branch 239 if (item->next) (5) Event if_fallthrough: Falling through to end of if statement 240 item->next->prev = item->prev; 241 else (6) Event if_end: End of if statement 242 queue->tail = item->prev; 243 244 virObjectUnref(item->cond); (7) Event freed_arg: "virFree" frees parameter "item". [details] 245 VIR_FREE(item); 246 } 247 John -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list