[lttng-dev] [PATCH lttng-tools] Fix: handle sys_futex() FUTEX_WAIT interrupted by signal

Mathieu Desnoyers mathieu.desnoyers at efficios.com
Mon Jul 6 17:28:34 EDT 2015


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 at efficios.com>
---
 src/common/futex.c | 37 ++++++++++++++++++++++++++++---------
 1 file changed, 28 insertions(+), 9 deletions(-)

diff --git a/src/common/futex.c b/src/common/futex.c
index 7f07b11..0781867 100644
--- a/src/common/futex.c
+++ b/src/common/futex.c
@@ -55,8 +55,11 @@ void futex_wait_update(int32_t *futex, int active)
 {
 	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);
 	}
@@ -84,10 +87,23 @@ void futex_nto1_wait(int32_t *futex)
 {
 	cmm_smp_mb();
 
-	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();
+		}
 	}
-
+end:
 	DBG("Futex n to 1 wait done");
 }
 
@@ -97,10 +113,13 @@ void futex_nto1_wait(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();
 	}
-
+end:
 	DBG("Futex n to 1 wake done");
 }
-- 
2.1.4




More information about the lttng-dev mailing list