about summary refs log tree commit diff
path: root/sysdeps/pthread/tst-cancel28.c
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2023-06-19 14:11:58 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2023-06-23 15:28:45 -0300
commit76d0104cedc5395e6742c0d867260963765d707b (patch)
tree39f890acbdbb86f283f2a2ea9c755e62b37795ce /sysdeps/pthread/tst-cancel28.c
parent99f9ae4ed0ba9f2c84520b78fd0eeed96a7ed40e (diff)
downloadglibc-76d0104cedc5395e6742c0d867260963765d707b.tar.gz
glibc-76d0104cedc5395e6742c0d867260963765d707b.tar.xz
glibc-76d0104cedc5395e6742c0d867260963765d707b.zip
linux: Do not spawn a new thread for SIGEV_THREAD (BZ 30558) azanella/bz30558-posix_timer
Diffstat (limited to 'sysdeps/pthread/tst-cancel28.c')
-rw-r--r--sysdeps/pthread/tst-cancel28.c44
1 files changed, 30 insertions, 14 deletions
diff --git a/sysdeps/pthread/tst-cancel28.c b/sysdeps/pthread/tst-cancel28.c
index ae55f38210..2eb78acede 100644
--- a/sysdeps/pthread/tst-cancel28.c
+++ b/sysdeps/pthread/tst-cancel28.c
@@ -28,48 +28,64 @@
 #include <support/xthread.h>
 
 static pthread_barrier_t barrier;
-static pthread_t timer_thread;
+
+#define VALUE1_INITIAL 0
+static __thread unsigned int value1 = VALUE1_INITIAL;
+#define VALUE2_INITIAL 0xdeadbeef
+static __thread unsigned int value2 = VALUE2_INITIAL;
+
+static int cl_called = 0;
 
 static void
 cl (void *arg)
 {
-  xpthread_barrier_wait (&barrier);
+  cl_called++;
+  xpthread_barrier_wait (&barrier); /* 1 */
 }
 
 static void
 thread_handler (union sigval sv)
 {
-  timer_thread = pthread_self ();
+  /* Check if thread state is correctly reset after a pthread_exit.  */
+  TEST_COMPARE (value1, VALUE1_INITIAL);
+  TEST_COMPARE (value2, VALUE2_INITIAL);
+
+  value1 = VALUE2_INITIAL;
+  value2 = VALUE1_INITIAL;
 
-  xpthread_barrier_wait (&barrier);
+  xpthread_barrier_wait (&barrier);  /* 0 */
 
   pthread_cleanup_push (cl, NULL);
-  while (1)
-    clock_nanosleep (CLOCK_REALTIME, 0, &(struct timespec) { 1, 0 }, NULL);
+  pthread_exit (NULL);
   pthread_cleanup_pop (0);
 }
 
 static int
 do_test (void)
 {
-  struct sigevent sev = { 0 };
-  sev.sigev_notify = SIGEV_THREAD;
-  sev.sigev_notify_function = &thread_handler;
+  struct sigevent sev = {
+    .sigev_notify = SIGEV_THREAD,
+    .sigev_notify_function = &thread_handler,
+  };
 
   timer_t timerid;
   TEST_COMPARE (timer_create (CLOCK_REALTIME, &sev, &timerid), 0);
 
   xpthread_barrier_init (&barrier, NULL, 2);
 
-  struct itimerspec trigger = { 0 };
-  trigger.it_value.tv_nsec = 1000000;
+  struct itimerspec trigger = { { 0, 1000000 }, { 0, 1000000 } };
   TEST_COMPARE (timer_settime (timerid, 0, &trigger, NULL), 0);
 
-  xpthread_barrier_wait (&barrier);
+  enum { TIMERS_TO_CHECK = 4 };
+  for (int i = 0; i < TIMERS_TO_CHECK; i++)
+    {
+      /* Check the thread local values.  */
+      xpthread_barrier_wait (&barrier);  /* 0 */
 
-  xpthread_cancel (timer_thread);
+      xpthread_barrier_wait (&barrier);  /* 1 */
+    }
 
-  xpthread_barrier_wait (&barrier);
+  TEST_COMPARE (cl_called, TIMERS_TO_CHECK);
 
   return 0;
 }