summaryrefslogtreecommitdiff
path: root/mutex.c
diff options
context:
space:
mode:
authorrpj <rpj>2000-12-28 05:43:49 +0000
committerrpj <rpj>2000-12-28 05:43:49 +0000
commitbab1896412f2d292ebd8d44bc9d6ddb58a8702b0 (patch)
tree09ecfc5f9042224f9b64c5e0aaaa09fcba22dd92 /mutex.c
parentc94735ecdde19c4de652efd144faeec1a729b1e0 (diff)
2000-10-10 Ross Johnson <rpj@setup1.ise.canberra.edu.au>
* misc.c (pthread_self): Restore Win32 "last error" cleared by TlsGetValue() call in pthread_getspecific() - "Steven Reddie" <smr@essemer.com.au> 2000-09-20 Ross Johnson <rpj@setup1.ise.canberra.edu.au> * mutex.c (pthread_mutex_lock): Record the owner of the mutex. This requires also keeping count of recursive locks ourselves rather than leaving it to Win32 since we need to know when to NULL the thread owner when the mutex is unlocked. (pthread_mutex_trylock): Likewise. (pthread_mutex_unlock): Check that the calling thread owns the mutex, decrement the recursive lock count, and NULL the owner if zero. Return EPERM if the mutex is owned by another thread. * implement.h (pthread_mutex_t_): Add ownerThread and lockCount members. - reported by Arthur Kantor <akantor@bexusa.com>
Diffstat (limited to 'mutex.c')
-rw-r--r--mutex.c48
1 files changed, 45 insertions, 3 deletions
diff --git a/mutex.c b/mutex.c
index 091c61e..d31b3b2 100644
--- a/mutex.c
+++ b/mutex.c
@@ -555,6 +555,12 @@ pthread_mutex_lock(pthread_mutex_t *mutex)
}
}
+ if (result == 0)
+ {
+ mx->ownerThread = pthread_self();
+ mx->lockCount++;
+ }
+
return(result);
}
@@ -578,13 +584,43 @@ pthread_mutex_unlock(pthread_mutex_t *mutex)
*/
if (mx != (pthread_mutex_t) PTW32_OBJECT_AUTO_INIT)
{
- if (mx->mutex == 0)
+ pthread_t self = pthread_self();
+
+ if (pthread_equal(mx->ownerThread, self) == 0)
{
- LeaveCriticalSection(&mx->cs);
+ int oldCount = mx->lockCount;
+ pthread_t oldOwner = mx->ownerThread;
+
+ if (mx->lockCount > 0)
+ {
+ mx->lockCount--;
+ }
+
+ if (mx->lockCount == 0)
+ {
+ mx->ownerThread = NULL;
+ }
+
+ if (mx->mutex == 0)
+ {
+ LeaveCriticalSection(&mx->cs);
+ }
+ else
+ {
+ if (!ReleaseMutex(mx->mutex))
+ {
+ result = EINVAL;
+ /*
+ * Put things back the way they were.
+ */
+ mx->lockCount = oldCount;
+ mx->ownerThread = oldOwner;
+ }
+ }
}
else
{
- result = (ReleaseMutex (mx->mutex) ? 0 : EINVAL);
+ result = EPERM;
}
}
else
@@ -643,5 +679,11 @@ pthread_mutex_trylock(pthread_mutex_t *mutex)
}
}
+ if (result == 0)
+ {
+ mx->ownerThread = pthread_self();
+ mx->lockCount++;
+ }
+
return(result);
}