diff options
author | Rich Felker <dalias@aerifal.cx> | 2011-03-17 20:41:37 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2011-03-17 20:41:37 -0400 |
commit | 047e434ef5fd5437a74f98f63c40a77a683f7f3f (patch) | |
tree | 30102ca55dc34c2b5ec078e3b3ab7891abcccb5f /src/thread/pthread_mutex_unlock.c | |
parent | 18c7ea8055cf733f168d2c74d7cc8523a360f5f1 (diff) | |
download | musl-047e434ef5fd5437a74f98f63c40a77a683f7f3f.tar.gz musl-047e434ef5fd5437a74f98f63c40a77a683f7f3f.tar.bz2 musl-047e434ef5fd5437a74f98f63c40a77a683f7f3f.tar.xz musl-047e434ef5fd5437a74f98f63c40a77a683f7f3f.zip |
implement robust mutexes
some of this code should be cleaned up, e.g. using macros for some of
the bit flags, masks, etc. nonetheless, the code is believed to be
working and correct at this point.
Diffstat (limited to 'src/thread/pthread_mutex_unlock.c')
-rw-r--r-- | src/thread/pthread_mutex_unlock.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/src/thread/pthread_mutex_unlock.c b/src/thread/pthread_mutex_unlock.c index 3733788d..67aa7ba5 100644 --- a/src/thread/pthread_mutex_unlock.c +++ b/src/thread/pthread_mutex_unlock.c @@ -2,14 +2,23 @@ int pthread_mutex_unlock(pthread_mutex_t *m) { + pthread_t self; + if (m->_m_type != PTHREAD_MUTEX_NORMAL) { - if (!m->_m_lock || m->_m_lock != __pthread_self()->tid) + self = __pthread_self(); + if ((m->_m_lock&0x1fffffff) != self->tid) return EPERM; - if (m->_m_type == PTHREAD_MUTEX_RECURSIVE && --m->_m_count) + if ((m->_m_type&3) == PTHREAD_MUTEX_RECURSIVE && --m->_m_count) return 0; + if (m->_m_type >= 4) { + self->robust_list.pending = &m->_m_next; + *(void **)m->_m_prev = m->_m_next; + if (m->_m_next) ((void **)m->_m_next)[-1] = m->_m_prev; + } } m->_m_lock = 0; if (m->_m_waiters) __wake(&m->_m_lock, 1, 0); + if (m->_m_type >= 4) self->robust_list.pending = 0; return 0; } |