Author: bonefish Date: 2009-11-29 10:54:58 +0100 (Sun, 29 Nov 2009) New Revision: 34337 Changeset: http://dev.haiku-os.org/changeset/34337/haiku Modified: haiku/trunk/headers/private/shared/locks.h haiku/trunk/src/system/libroot/os/locks.cpp Log: Added recursive lock implementation (an adapted kernel version). Modified: haiku/trunk/headers/private/shared/locks.h =================================================================== --- haiku/trunk/headers/private/shared/locks.h 2009-11-29 09:20:58 UTC (rev 34336) +++ haiku/trunk/headers/private/shared/locks.h 2009-11-29 09:54:58 UTC (rev 34337) @@ -40,6 +40,20 @@ status_t rw_lock_write_lock(rw_lock *lock); status_t rw_lock_write_unlock(rw_lock *lock); + +typedef struct recursive_lock { + mutex lock; + thread_id holder; + int recursion; +} recursive_lock; + +extern status_t recursive_lock_init(recursive_lock *lock, const char *name); +extern void recursive_lock_destroy(recursive_lock *lock); +extern status_t recursive_lock_lock(recursive_lock *lock); +extern status_t recursive_lock_trylock(recursive_lock *lock); +extern void recursive_lock_unlock(recursive_lock *lock); +extern int32 recursive_lock_get_recursion(recursive_lock *lock); + #ifdef __cplusplus } // extern "C" Modified: haiku/trunk/src/system/libroot/os/locks.cpp =================================================================== --- haiku/trunk/src/system/libroot/os/locks.cpp 2009-11-29 09:20:58 UTC (rev 34336) +++ haiku/trunk/src/system/libroot/os/locks.cpp 2009-11-29 09:54:58 UTC (rev 34337) @@ -2,7 +2,16 @@ * Copyright 2009, Michael Lotz, mmlr@xxxxxxxxx * Distributed under the terms of the MIT License. */ +/* + * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@xxxxxxx + * Copyright 2002-2009, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx All rights reserved. + * Distributed under the terms of the MIT License. + * + * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. + */ + #include <locks.h> #include <syscalls.h> #include <user_thread.h> @@ -10,6 +19,9 @@ #include <OS.h> +// #pragma mark - mutex + + status_t mutex_init(mutex *lock, const char *name) { @@ -55,6 +67,9 @@ } +// #pragma mark - R/W lock + + typedef struct rw_lock_waiter { rw_lock_waiter * next; thread_id thread; @@ -248,3 +263,65 @@ rw_lock_unblock(lock); return B_OK; } + + +// #pragma mark - recursive lock + + +int32 +recursive_lock_get_recursion(recursive_lock *lock) +{ + if (lock->holder == find_thread(NULL)) + return lock->recursion; + + return -1; +} + + +status_t +recursive_lock_init(recursive_lock *lock, const char *name) +{ + lock->holder = -1; + lock->recursion = 0; + return mutex_init(&lock->lock, name != NULL ? name : "recursive lock"); +} + + +void +recursive_lock_destroy(recursive_lock *lock) +{ + if (lock == NULL) + return; + + mutex_destroy(&lock->lock); +} + + +status_t +recursive_lock_lock(recursive_lock *lock) +{ + thread_id thread = find_thread(NULL); + + if (thread != lock->holder) { + mutex_lock(&lock->lock); + lock->holder = thread; + } + + lock->recursion++; + return B_OK; +} + + +void +recursive_lock_unlock(recursive_lock *lock) +{ + if (find_thread(NULL) != lock->holder) { + debugger("recursive_lock unlocked by non-holder thread!\n"); + return; + } + + if (--lock->recursion == 0) { + lock->holder = -1; + mutex_unlock(&lock->lock); + } +}