]> sourceware.org Git - glibc.git/commitdiff
Fix nptl semaphore cleanup invocation.
authorDavid S. Miller <davem@davemloft.net>
Mon, 5 Sep 2011 17:01:52 +0000 (10:01 -0700)
committerDavid S. Miller <davem@davemloft.net>
Mon, 5 Sep 2011 17:01:52 +0000 (10:01 -0700)
nptl/ChangeLog
nptl/sysdeps/unix/sysv/linux/sem_timedwait.c
nptl/sysdeps/unix/sysv/linux/sem_wait.c
nptl/sysdeps/unix/sysv/linux/sparc/sem_timedwait.c
nptl/sysdeps/unix/sysv/linux/sparc/sem_wait.c
nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c
nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sem_wait.c

index c44ce2af6fece5bc6b79a79cb6da36e8056272f0..caae5dcf3ca602a159fb92c0b5ba8fec55b95ffe 100644 (file)
@@ -1,3 +1,17 @@
+2011-09-05  David S. Miller  <davem@davemloft.net>
+
+       * sysdeps/unix/sysv/linux/sem_timedwait.c (do_futex_timed_wait):
+       New function.
+       (sem_timedwait): Call it to force an exception region around
+       the async cancel enable and the futex operation.
+       * sysdeps/unix/sysv/linux/sparc/sem_timedwait.c: Likewise.
+       * sysdeps/unix/sysv/linux/sparc/sparc32/sem_timedwait.c: Likewise.
+       * sysdeps/unix/sysv/linux/sem_wait.c (do_futex_wait): New function.
+       (__new_sem_wait): Call it to force an exception region around
+       the async cancel enable and the futex operation.
+       * sysdeps/unix/sysv/linux/sparc/sem_wait.c: Likewise.
+       * sysdeps/unix/sysv/linux/sparc/sparc32/sem_wait.c: Likewise.
+
 2011-08-31  Andreas Schwab  <schwab@redhat.com>
 
        * allocatestack.c (setxid_mark_thread): Ensure that the exiting
index fdf0d74011150bb1fc9b43ced5ed05118861d2b6..cb3b78fe679b881ecbe43db5d681c1e9833b1687 100644 (file)
 
 extern void __sem_wait_cleanup (void *arg) attribute_hidden;
 
+/* This is in a seperate function in order to make sure gcc
+   puts the call site into an exception region, and thus the
+   cleanups get properly run.  */
+static int
+__attribute__ ((noinline))
+do_futex_timed_wait (struct new_sem *isem, struct timespec *rt)
+{
+  int err, oldtype = __pthread_enable_asynccancel ();
+
+  err = lll_futex_timed_wait (&isem->value, 0, rt,
+                             isem->private ^ FUTEX_PRIVATE_FLAG);
+
+  __pthread_disable_asynccancel (oldtype);
+  return err;
+}
 
 int
 sem_timedwait (sem_t *sem, const struct timespec *abstime)
@@ -80,16 +95,7 @@ sem_timedwait (sem_t *sem, const struct timespec *abstime)
       /* Do wait.  */
       rt.tv_sec = sec;
       rt.tv_nsec = nsec;
-
-      /* Enable asynchronous cancellation.  Required by the standard.  */
-      int oldtype = __pthread_enable_asynccancel ();
-
-      err = lll_futex_timed_wait (&isem->value, 0, &rt,
-                                 isem->private ^ FUTEX_PRIVATE_FLAG);
-
-      /* Disable asynchronous cancellation.  */
-      __pthread_disable_asynccancel (oldtype);
-
+      err = do_futex_timed_wait(isem, &rt);
       if (err != 0 && err != -EWOULDBLOCK)
        {
          __set_errno (-err);
index 20e2b481dff3fd63a25a859a79e1a03dab828ab3..602c38246f1afe6a453a0405cca2e03b876636e4 100644 (file)
@@ -37,6 +37,20 @@ __sem_wait_cleanup (void *arg)
   atomic_decrement (&isem->nwaiters);
 }
 
+/* This is in a seperate function in order to make sure gcc
+   puts the call site into an exception region, and thus the
+   cleanups get properly run.  */
+static int
+__attribute__ ((noinline))
+do_futex_wait (struct new_sem *isem)
+{
+  int err, oldtype = __pthread_enable_asynccancel ();
+
+  err = lll_futex_wait (&isem->value, 0, isem->private ^ FUTEX_PRIVATE_FLAG);
+
+  __pthread_disable_asynccancel (oldtype);
+  return err;
+}
 
 int
 __new_sem_wait (sem_t *sem)
@@ -53,15 +67,7 @@ __new_sem_wait (sem_t *sem)
 
   while (1)
     {
-      /* Enable asynchronous cancellation.  Required by the standard.  */
-      int oldtype = __pthread_enable_asynccancel ();
-
-      err = lll_futex_wait (&isem->value, 0,
-                           isem->private ^ FUTEX_PRIVATE_FLAG);
-
-      /* Disable asynchronous cancellation.  */
-      __pthread_disable_asynccancel (oldtype);
-
+      err = do_futex_wait(isem);
       if (err != 0 && err != -EWOULDBLOCK)
        {
          __set_errno (-err);
index 01952f3f9ab6b453d4b8a606cca4716363f69aec..fdd09affeaad71ca2885676e6734c1c812e0a8ce 100644 (file)
 
 extern void __sem_wait_cleanup (void *arg) attribute_hidden;
 
+/* This is in a seperate function in order to make sure gcc
+   puts the call site into an exception region, and thus the
+   cleanups get properly run.  */
+static int
+__attribute__ ((noinline))
+do_futex_timed_wait (struct sparc_new_sem *isem, struct timespec *rt)
+{
+  int err, oldtype = __pthread_enable_asynccancel ();
+
+  err = lll_futex_timed_wait (&isem->value, 0, rt,
+                             isem->private ^ FUTEX_PRIVATE_FLAG);
+
+  __pthread_disable_asynccancel (oldtype);
+  return err;
+}
 
 int
 sem_timedwait (sem_t *sem, const struct timespec *abstime)
@@ -80,16 +95,7 @@ sem_timedwait (sem_t *sem, const struct timespec *abstime)
       /* Do wait.  */
       rt.tv_sec = sec;
       rt.tv_nsec = nsec;
-
-      /* Enable asynchronous cancellation.  Required by the standard.  */
-      int oldtype = __pthread_enable_asynccancel ();
-
-      err = lll_futex_timed_wait (&isem->value, 0, &rt,
-                                 isem->private ^ FUTEX_PRIVATE_FLAG);
-
-      /* Disable asynchronous cancellation.  */
-      __pthread_disable_asynccancel (oldtype);
-
+      err = do_futex_timed_wait(isem, &rt);
       if (err != 0 && err != -EWOULDBLOCK)
        {
          __set_errno (-err);
index a846f20601846cdef9cc434f5dfeffd33b5f88b5..4a2c9357a07db9f429f195937b900fa360443877 100644 (file)
@@ -37,6 +37,20 @@ __sem_wait_cleanup (void *arg)
   atomic_decrement (&isem->nwaiters);
 }
 
+/* This is in a seperate function in order to make sure gcc
+   puts the call site into an exception region, and thus the
+   cleanups get properly run.  */
+static int
+__attribute__ ((noinline))
+do_futex_wait (struct sparc_new_sem *isem)
+{
+  int err, oldtype = __pthread_enable_asynccancel ();
+
+  err = lll_futex_wait (&isem->value, 0, isem->private ^ FUTEX_PRIVATE_FLAG);
+
+  __pthread_disable_asynccancel (oldtype);
+  return err;
+}
 
 int
 __new_sem_wait (sem_t *sem)
@@ -53,15 +67,7 @@ __new_sem_wait (sem_t *sem)
 
   while (1)
     {
-      /* Enable asynchronous cancellation.  Required by the standard.  */
-      int oldtype = __pthread_enable_asynccancel ();
-
-      err = lll_futex_wait (&isem->value, 0,
-                           isem->private ^ FUTEX_PRIVATE_FLAG);
-
-      /* Disable asynchronous cancellation.  */
-      __pthread_disable_asynccancel (oldtype);
-
+      err = do_futex_wait(isem);
       if (err != 0 && err != -EWOULDBLOCK)
        {
          __set_errno (-err);
index 55f3e2e0753058020ce297105d9285a13caaad60..90edbc5dd092f46dae96a1a66e7368945b04a8af 100644 (file)
 
 extern void __sem_wait_cleanup (void *arg) attribute_hidden;
 
+/* This is in a seperate function in order to make sure gcc
+   puts the call site into an exception region, and thus the
+   cleanups get properly run.  */
+static int
+__attribute__ ((noinline))
+do_futex_timed_wait (struct sparc_new_sem *isem, struct timespec *rt)
+{
+  int err, oldtype = __pthread_enable_asynccancel ();
+
+  err = lll_futex_timed_wait (&isem->value, 0, rt,
+                             isem->private ^ FUTEX_PRIVATE_FLAG);
+
+  __pthread_disable_asynccancel (oldtype);
+  return err;
+}
 
 int
 sem_timedwait (sem_t *sem, const struct timespec *abstime)
@@ -99,16 +114,7 @@ sem_timedwait (sem_t *sem, const struct timespec *abstime)
       /* Do wait.  */
       rt.tv_sec = sec;
       rt.tv_nsec = nsec;
-
-      /* Enable asynchronous cancellation.  Required by the standard.  */
-      int oldtype = __pthread_enable_asynccancel ();
-
-      err = lll_futex_timed_wait (&isem->value, 0, &rt,
-                                 isem->private ^ FUTEX_PRIVATE_FLAG);
-
-      /* Disable asynchronous cancellation.  */
-      __pthread_disable_asynccancel (oldtype);
-
+      err = do_futex_timed_wait(isem, &rt);
       if (err != 0 && err != -EWOULDBLOCK)
        {
          __set_errno (-err);
index b14f976a61f0aab28301bf90a1e0a6f5b1d4b93c..8fba4b7d7ede230230dc05878bc05c7d650084ae 100644 (file)
@@ -44,6 +44,20 @@ __sem_wait_cleanup (void *arg)
     }
 }
 
+/* This is in a seperate function in order to make sure gcc
+   puts the call site into an exception region, and thus the
+   cleanups get properly run.  */
+static int
+__attribute__ ((noinline))
+do_futex_wait (struct sparc_new_sem *isem)
+{
+  int err, oldtype = __pthread_enable_asynccancel ();
+
+  err = lll_futex_wait (&isem->value, 0, isem->private ^ FUTEX_PRIVATE_FLAG);
+
+  __pthread_disable_asynccancel (oldtype);
+  return err;
+}
 
 int
 __new_sem_wait (sem_t *sem)
@@ -77,15 +91,7 @@ __new_sem_wait (sem_t *sem)
 
   while (1)
     {
-      /* Enable asynchronous cancellation.  Required by the standard.  */
-      int oldtype = __pthread_enable_asynccancel ();
-
-      err = lll_futex_wait (&isem->value, 0,
-                           isem->private ^ FUTEX_PRIVATE_FLAG);
-
-      /* Disable asynchronous cancellation.  */
-      __pthread_disable_asynccancel (oldtype);
-
+      err = do_futex_wait(isem);
       if (err != 0 && err != -EWOULDBLOCK)
        {
          __set_errno (-err);
This page took 0.063644 seconds and 5 git commands to generate.