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(a)redhat.com>
---
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