Fix: wfcqueue nonblocking dequeue
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 20 Nov 2012 04:22:50 +0000 (23:22 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 5 Dec 2012 10:48:00 +0000 (05:48 -0500)
Failures were not handled in the nonblocking dequeue implementation.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
urcu/static/wfcqueue.h

index 8733771c462d4e51cb384ddd50fe4ba4f3af79f8..a284b580af7d8777087ba17e6094c40e03abecc9 100644 (file)
@@ -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;
+               }
        }
 
        /*
This page took 0.029653 seconds and 4 git commands to generate.