Version 0.9.7
[urcu.git] / urcu-wait.h
index d00842a04b26484d67bdde4ed9a7550baf926039..47ac5eb35884f437ca299e48cf656e2c301557f7 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <urcu/uatomic.h>
 #include <urcu/wfstack.h>
+#include "urcu-die.h"
 
 /*
  * Number of busy-loop attempts before waiting on futex for grace period
@@ -59,8 +60,13 @@ struct urcu_wait_queue {
        struct cds_wfs_stack stack;
 };
 
-#define URCU_WAIT_QUEUE_HEAD_INIT(name)                        \
-       { .stack.head = CDS_WFS_END, .stack.lock = PTHREAD_MUTEX_INITIALIZER }
+#define URCU_WAIT_QUEUE_HEAD_INIT(name)                                \
+       {                                                       \
+                .stack = {                                     \
+                       .head = CDS_WFS_END,                    \
+                       .lock = PTHREAD_MUTEX_INITIALIZER,      \
+               },                                              \
+       }
 
 #define DECLARE_URCU_WAIT_QUEUE(name)                  \
        struct urcu_wait_queue name
@@ -122,8 +128,11 @@ void urcu_adaptative_wake_up(struct urcu_wait_node *wait)
        cmm_smp_mb();
        assert(uatomic_read(&wait->state) == URCU_WAIT_WAITING);
        uatomic_set(&wait->state, URCU_WAIT_WAKEUP);
-       if (!(uatomic_read(&wait->state) & URCU_WAIT_RUNNING))
-               futex_noasync(&wait->state, FUTEX_WAKE, 1, NULL, NULL, 0);
+       if (!(uatomic_read(&wait->state) & URCU_WAIT_RUNNING)) {
+               if (futex_noasync(&wait->state, FUTEX_WAKE, 1,
+                               NULL, NULL, 0) < 0)
+                       urcu_die(errno);
+       }
        /* Allow teardown of struct urcu_wait memory. */
        uatomic_or(&wait->state, URCU_WAIT_TEARDOWN);
 }
@@ -144,8 +153,20 @@ void urcu_adaptative_busy_wait(struct urcu_wait_node *wait)
                        goto skip_futex_wait;
                caa_cpu_relax();
        }
-       futex_noasync(&wait->state, FUTEX_WAIT,
-               URCU_WAIT_WAITING, NULL, NULL, 0);
+       while (futex_noasync(&wait->state, FUTEX_WAIT, URCU_WAIT_WAITING,
+                       NULL, NULL, 0)) {
+               switch (errno) {
+               case EWOULDBLOCK:
+                       /* Value already changed. */
+                       goto skip_futex_wait;
+               case EINTR:
+                       /* Retry if interrupted by signal. */
+                       break;  /* Get out of switch. */
+               default:
+                       /* Unexpected error. */
+                       urcu_die(errno);
+               }
+       }
 skip_futex_wait:
 
        /* Tell waker thread than we are running. */
This page took 0.023363 seconds and 4 git commands to generate.