X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=urcu%2Fstatic%2Fwfcqueue.h;h=a284b580af7d8777087ba17e6094c40e03abecc9;hb=dfb65fd3cc75f660f35feedd2e14b000dbe39a4b;hp=120a5989e6a4341c7d2ec8a4fc719812235542ae;hpb=47215721095cf47e110f113d26f9e61514405a4c;p=urcu.git diff --git a/urcu/static/wfcqueue.h b/urcu/static/wfcqueue.h index 120a598..a284b58 100644 --- a/urcu/static/wfcqueue.h +++ b/urcu/static/wfcqueue.h @@ -6,8 +6,8 @@ * * Userspace RCU library - Concurrent Queue with Wait-Free Enqueue/Blocking Dequeue * - * TO BE INCLUDED ONLY IN LGPL-COMPATIBLE CODE. See wfcqueue.h for linking - * dynamically with the userspace rcu library. + * TO BE INCLUDED ONLY IN LGPL-COMPATIBLE CODE. See urcu/wfcqueue.h for + * linking dynamically with the userspace rcu library. * * Copyright 2010-2012 - Mathieu Desnoyers * Copyright 2011-2012 - Lai Jiangshan @@ -312,6 +312,8 @@ ___cds_wfcq_dequeue(struct cds_wfcq_head *head, return NULL; node = ___cds_wfcq_node_sync_next(&head->node, blocking); + if (!blocking && node == CDS_WFCQ_WOULDBLOCK) + return CDS_WFCQ_WOULDBLOCK; if ((next = CMM_LOAD_SHARED(node->next)) == NULL) { /* @@ -332,6 +334,15 @@ ___cds_wfcq_dequeue(struct cds_wfcq_head *head, if (uatomic_cmpxchg(&tail->p, node, &head->node) == node) return node; next = ___cds_wfcq_node_sync_next(node, blocking); + /* + * In nonblocking mode, if we would need to block to + * get node's next, set the head next node pointer + * (currently NULL) back to its original value. + */ + if (!blocking && next == CDS_WFCQ_WOULDBLOCK) { + head->node.next = node; + return CDS_WFCQ_WOULDBLOCK; + } } /*