[LTP] [PATCH v2] openposix: timers/twoevtimers: Wait for both timer signals

Jan Stancek jstancek@redhat.com
Fri Oct 9 12:52:47 CEST 2026


The test arms two timers with the same absolute expiration time and
then does a single sleep() before checking that both signals arrived.
sleep() returns as soon as the first signal interrupts it, and the
kernel delivers the two signals one at a time. This sporadically
leads to failure:

  Caught abort signal
  Test FAILED

even though the second timer fires microseconds later.

Keep sleeping on the remaining time until both signals have been caught
or the LONGTIME budget, which was defined but never used, runs out. Use
nanosleep() rather than sleep() for this, since sleep() returns the
unslept time in whole seconds and the fraction would be lost on every
interruption. Make the counters volatile sig_atomic_t and print from the
handlers with the async-signal-safe PTS_WRITE_MSG() instead of printf().

Arm the timers to expire 50ms from now instead of 3 seconds, so the test
passes in about 50ms, and lower LONGTIME, the upper bound for when a
signal does not arrive, from 5 to 3 seconds. Also correct the header
comment: the timers live in the same process, not in different
processes, and the test only checks that both of them expire, not that
they expire at the same time.

Signed-off-by: Jan Stancek <jstancek@redhat.com>
---
 .../functional/timers/timers/twoevtimers.c    | 51 ++++++++++++++-----
 1 file changed, 38 insertions(+), 13 deletions(-)

Changes in v2:
 - use nanosleep
 - make signals arrive in 50ms instead of 1 second

diff --git a/testcases/open_posix_testsuite/functional/timers/timers/twoevtimers.c b/testcases/open_posix_testsuite/functional/timers/timers/twoevtimers.c
index 0e46229777fe..1b2b20a5c399 100644
--- a/testcases/open_posix_testsuite/functional/timers/timers/twoevtimers.c
+++ b/testcases/open_posix_testsuite/functional/timers/timers/twoevtimers.c
@@ -5,9 +5,16 @@
  * of this license, see the COPYING file at the top level of this
  * source tree.
  *
- * Test having two timers in different processes set to expire at the
- * same time, and ensure they both expire at the same time.
+ * Test having two timers in the same process, armed with the same
+ * absolute expiration time but delivering different signals, and ensure
+ * that both of them expire.
+ *
+ * Note that the test does not (and cannot) verify that the two signals
+ * are delivered simultaneously.  Signals are delivered one at a time, so
+ * the first one interrupts nanosleep() while the second one may still be
+ * on its way.  Keep waiting until both have arrived or LONGTIME elapses.
  */
+#include <errno.h>
 #include <stdio.h>
 #include <time.h>
 #include <signal.h>
@@ -16,24 +23,25 @@
 #include <sys/wait.h>
 #include <unistd.h>
 #include "posixtest.h"
+#include "timespec.h"
 
-#define EXPIREDELTA 3
-#define LONGTIME 5
+#define EXPIREDELTA_NS 50000000
+#define LONGTIME 3
 
 #define CHILDPASS 1
 
-static int caughtabort = 0;
-static int caughtalarm = 0;
+static volatile sig_atomic_t caughtabort = 0;
+static volatile sig_atomic_t caughtalarm = 0;
 
-static void handler_abrt(int signo)
+static void handler_abrt(int signo PTS_ATTRIBUTE_UNUSED)
 {
-	printf("Caught abort signal\n");
+	PTS_WRITE_MSG("Caught abort signal\n");
 	caughtabort++;
 }
 
-static void handler_alrm(int signo)
+static void handler_alrm(int signo PTS_ATTRIBUTE_UNUSED)
 {
-	printf("Caught alarm signal\n");
+	PTS_WRITE_MSG("Caught alarm signal\n");
 	caughtalarm++;
 }
 
@@ -45,6 +53,7 @@ int test_main(int argc, char **argv)
 	struct timespec ts;
 	struct itimerspec its;
 	int flags = 0;
+	struct timespec left = { .tv_sec = LONGTIME };
 
 	act1.sa_handler = handler_abrt;
 	act1.sa_flags = 0;
@@ -77,8 +86,12 @@ int test_main(int argc, char **argv)
 		return PTS_UNRESOLVED;
 	}
 
-	its.it_value.tv_sec = ts.tv_sec + EXPIREDELTA;
-	its.it_value.tv_nsec = ts.tv_nsec;
+	its.it_value.tv_sec = ts.tv_sec;
+	its.it_value.tv_nsec = ts.tv_nsec + EXPIREDELTA_NS;
+	if (its.it_value.tv_nsec >= NSEC_IN_SEC) {
+		its.it_value.tv_sec++;
+		its.it_value.tv_nsec -= NSEC_IN_SEC;
+	}
 	its.it_interval.tv_sec = 0;
 	its.it_interval.tv_nsec = 0;
 
@@ -93,7 +106,19 @@ int test_main(int argc, char **argv)
 		return PTS_UNRESOLVED;
 	}
 
-	sleep(EXPIREDELTA + 1);
+	/*
+	 * nanosleep() returns early when the first signal arrives; keep
+	 * waiting on the remaining time until the second one has been
+	 * delivered as well or we time out.
+	 */
+	while (!(caughtalarm && caughtabort)) {
+		if (nanosleep(&left, &left) == 0)
+			break;
+		if (errno != EINTR) {
+			perror("nanosleep() did not return success\n");
+			return PTS_UNRESOLVED;
+		}
+	}
 
 	if ((caughtalarm == 1) && (caughtabort == 1)) {
 		printf("Test PASSED\n");
-- 
2.56.0



More information about the ltp mailing list