summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
2c57e06)
We need to handle EINTR returned by sys_futex() FUTEX_WAIT, otherwise a
signal interrupting this system call could make sys_futex return too
early, and therefore cause a synchronization issue.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
{
if (active) {
uatomic_set(futex, 1);
{
if (active) {
uatomic_set(futex, 1);
- futex_async(futex, FUTEX_WAKE,
- INT_MAX, NULL, NULL, 0);
+ if (futex_async(futex, FUTEX_WAKE,
+ INT_MAX, NULL, NULL, 0) < 0) {
+ PERROR("futex_async");
+ abort();
+ }
} else {
uatomic_set(futex, 0);
}
} else {
uatomic_set(futex, 0);
}
- if (uatomic_read(futex) == -1) {
- futex_async(futex, FUTEX_WAIT, -1, NULL, NULL, 0);
+ if (uatomic_read(futex) != -1)
+ goto end;
+ while (futex_async(futex, FUTEX_WAIT, -1, NULL, NULL, 0)) {
+ switch (errno) {
+ case EWOULDBLOCK:
+ /* Value already changed. */
+ goto end;
+ case EINTR:
+ /* Retry if interrupted by signal. */
+ break; /* Get out of switch. */
+ default:
+ /* Unexpected error. */
+ PERROR("futex_async");
+ abort();
+ }
DBG("Futex n to 1 wait done");
}
DBG("Futex n to 1 wait done");
}
LTTNG_HIDDEN
void futex_nto1_wake(int32_t *futex)
{
LTTNG_HIDDEN
void futex_nto1_wake(int32_t *futex)
{
- if (caa_unlikely(uatomic_read(futex) == -1)) {
- uatomic_set(futex, 0);
- futex_async(futex, FUTEX_WAKE, 1, NULL, NULL, 0);
+ if (caa_unlikely(uatomic_read(futex) != -1))
+ goto end;
+ uatomic_set(futex, 0);
+ if (futex_async(futex, FUTEX_WAKE, 1, NULL, NULL, 0) < 0) {
+ PERROR("futex_async");
+ abort();
DBG("Futex n to 1 wake done");
}
DBG("Futex n to 1 wake done");
}