X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fcommon%2Fwaiter.c;h=db2de6557f5df5a5465d66c8e2df591202953983;hb=1824a395cf05bfaf8ef3353984c16e70c2a93ca9;hp=779754e1ba168cd2d3e115bfc39e82d81109728d;hpb=717918b72e07062b62f96baaf1ae480b0a929617;p=lttng-tools.git diff --git a/src/common/waiter.c b/src/common/waiter.c index 779754e1b..db2de6557 100644 --- a/src/common/waiter.c +++ b/src/common/waiter.c @@ -52,15 +52,25 @@ void lttng_waiter_wait(struct lttng_waiter *waiter) } caa_cpu_relax(); } - while (futex_noasync(&waiter->state, FUTEX_WAIT, WAITER_WAITING, - NULL, NULL, 0)) { + while (uatomic_read(&waiter->state) == WAITER_WAITING) { + if (!futex_noasync(&waiter->state, FUTEX_WAIT, WAITER_WAITING, NULL, NULL, 0)) { + /* + * Prior queued wakeups queued by unrelated code + * using the same address can cause futex wait to + * return 0 even through the futex value is still + * WAITER_WAITING (spurious wakeups). Check + * the value again in user-space to validate + * whether it really differs from WAITER_WAITING. + */ + continue; + } switch (errno) { - case EWOULDBLOCK: + case EAGAIN: /* Value already changed. */ goto skip_futex_wait; case EINTR: /* Retry if interrupted by signal. */ - break; /* Get out of switch. */ + break; /* Get out of switch. Check again. */ default: /* Unexpected error. */ PERROR("futex_noasync");