diff options
Diffstat (limited to 'sysdeps/generic/pt-mutex-timedlock.c')
-rw-r--r-- | sysdeps/generic/pt-mutex-timedlock.c | 56 |
1 files changed, 46 insertions, 10 deletions
diff --git a/sysdeps/generic/pt-mutex-timedlock.c b/sysdeps/generic/pt-mutex-timedlock.c index 5e222bd..883e50a 100644 --- a/sysdeps/generic/pt-mutex-timedlock.c +++ b/sysdeps/generic/pt-mutex-timedlock.c @@ -1,5 +1,5 @@ /* Lock a mutex with a timeout. Generic version. - Copyright (C) 2000, 2002, 2005 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2005, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -31,13 +31,33 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex, const struct timespec *abstime) { struct __pthread *self; + const struct __pthread_mutexattr *attr = mutex->attr; + + if (attr == __PTHREAD_ERRORCHECK_MUTEXATTR) + attr = &__pthread_errorcheck_mutexattr; + if (attr == __PTHREAD_RECURSIVE_MUTEXATTR) + attr = &__pthread_recursive_mutexattr; __pthread_spin_lock (&mutex->__lock); if (__pthread_spin_trylock (&mutex->__held) == 0) /* Successfully acquired the lock. */ { - if (mutex->attr) - switch (mutex->attr->mutex_type) +#ifdef ALWAYS_TRACK_MUTEX_OWNER +#ifndef NDEBUG + self = _pthread_self (); + if (self) + /* The main thread may take a lock before the library is fully + initialized, in particular, before the main thread has a + TCB. */ + { + assert (! mutex->owner); + mutex->owner = _pthread_self (); + } +#endif +#endif + + if (attr) + switch (attr->mutex_type) { case PTHREAD_MUTEX_NORMAL: break; @@ -59,14 +79,18 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex, /* The lock is busy. */ self = _pthread_self (); + assert (self); - if (mutex->attr) + if (! attr || attr->mutex_type == PTHREAD_MUTEX_NORMAL) + { +#if defined(ALWAYS_TRACK_MUTEX_OWNER) + assert (mutex->owner != self); +#endif + } + else { - switch (mutex->attr->mutex_type) + switch (attr->mutex_type) { - case PTHREAD_MUTEX_NORMAL: - break; - case PTHREAD_MUTEX_ERRORCHECK: if (mutex->owner == self) { @@ -89,6 +113,11 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex, } } +#if !defined(ALWAYS_TRACK_MUTEX_OWNER) + if (attr && attr->mutex_type != PTHREAD_MUTEX_NORMAL) +#endif + assert (mutex->owner); + if (abstime && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)) return EINVAL; @@ -123,8 +152,15 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex, else __pthread_block (self); - if (mutex->attr) - switch (mutex->attr->mutex_type) +#if !defined(ALWAYS_TRACK_MUTEX_OWNER) + if (attr && attr->mutex_type != PTHREAD_MUTEX_NORMAL) +#endif + { + assert (mutex->owner == self); + } + + if (attr) + switch (attr->mutex_type) { case PTHREAD_MUTEX_NORMAL: break; |