Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libpthread PR/44756: Sad Clouds: Prevent leakage of errn...



details:   https://anonhg.NetBSD.org/src/rev/11c7990db766
branches:  trunk
changeset: 793244:11c7990db766
user:      christos <christos%NetBSD.org@localhost>
date:      Fri Jan 31 19:22:00 2014 +0000

description:
PR/44756: Sad Clouds: Prevent leakage of errno = ESRCH from _lwp_park. This
has two parts:
        - in pthread_cond_timedwait() if the thread we are trying to unpark
          exited, retry the the _lwp_park call without it.
        - pthread_mutex() was affecting errno since it is calling _lwp_park()
          from pthread_mutex_lock_slow(). preserve the original errno.
Note that the example problem still causes an occassional deadlock on machines
with many CPUs and it is the same deadlock we observe with named.

diffstat:

 lib/libpthread/pthread_cond.c  |  14 ++++++++------
 lib/libpthread/pthread_mutex.c |   7 +++++--
 2 files changed, 13 insertions(+), 8 deletions(-)

diffs (77 lines):

diff -r 4020be7d39ff -r 11c7990db766 lib/libpthread/pthread_cond.c
--- a/lib/libpthread/pthread_cond.c     Fri Jan 31 18:49:35 2014 +0000
+++ b/lib/libpthread/pthread_cond.c     Fri Jan 31 19:22:00 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pthread_cond.c,v 1.61 2013/04/01 13:28:21 christos Exp $       */
+/*     $NetBSD: pthread_cond.c,v 1.62 2014/01/31 19:22:00 christos Exp $       */
 
 /*-
  * Copyright (c) 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -46,7 +46,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread_cond.c,v 1.61 2013/04/01 13:28:21 christos Exp $");
+__RCSID("$NetBSD: pthread_cond.c,v 1.62 2014/01/31 19:22:00 christos Exp $");
 
 #include <stdlib.h>
 #include <errno.h>
@@ -184,10 +184,12 @@
                pthread_mutex_unlock(mutex);
                self->pt_willpark = 0;
                self->pt_blocking++;
-               retval = _lwp_park(abstime, self->pt_unpark,
-                   __UNVOLATILE(&mutex->ptm_waiters),
-                   __UNVOLATILE(&mutex->ptm_waiters));
-               self->pt_unpark = 0;
+               do {
+                       retval = _lwp_park(abstime, self->pt_unpark,
+                           __UNVOLATILE(&mutex->ptm_waiters),
+                           __UNVOLATILE(&mutex->ptm_waiters));
+                       self->pt_unpark = 0;
+               } while (retval == -1 && errno == ESRCH);
                self->pt_blocking--;
                membar_sync();
                pthread_mutex_lock(mutex);
diff -r 4020be7d39ff -r 11c7990db766 lib/libpthread/pthread_mutex.c
--- a/lib/libpthread/pthread_mutex.c    Fri Jan 31 18:49:35 2014 +0000
+++ b/lib/libpthread/pthread_mutex.c    Fri Jan 31 19:22:00 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pthread_mutex.c,v 1.56 2013/03/21 16:49:12 christos Exp $      */
+/*     $NetBSD: pthread_mutex.c,v 1.57 2014/01/31 19:22:00 christos Exp $      */
 
 /*-
  * Copyright (c) 2001, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -47,7 +47,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread_mutex.c,v 1.56 2013/03/21 16:49:12 christos Exp $");
+__RCSID("$NetBSD: pthread_mutex.c,v 1.57 2014/01/31 19:22:00 christos Exp $");
 
 #include <sys/types.h>
 #include <sys/lwpctl.h>
@@ -213,6 +213,7 @@
 {
        void *waiters, *new, *owner, *next;
        pthread_t self;
+       int serrno;
 
        pthread__error(EINVAL, "Invalid mutex",
            ptm->ptm_magic == _PT_MUTEX_MAGIC);
@@ -232,6 +233,7 @@
                        return EDEADLK;
        }
 
+       serrno = errno;
        for (;; owner = ptm->ptm_owner) {
                /* Spin while the owner is running. */
                owner = pthread__mutex_spin(ptm, owner);
@@ -244,6 +246,7 @@
                                next = atomic_cas_ptr(&ptm->ptm_owner, owner,
                                    new);
                                if (next == owner) {
+                                       errno = serrno;
 #ifndef PTHREAD__ATOMIC_IS_MEMBAR
                                        membar_enter();
 #endif



Home | Main Index | Thread Index | Old Index