Added recursive lock implementation (an adapted kernel version).
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34337 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
d78ffde5d1
commit
93b9f21335
@ -40,6 +40,20 @@ status_t rw_lock_read_unlock(rw_lock *lock);
|
||||
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"
|
||||
|
||||
|
@ -2,6 +2,15 @@
|
||||
* Copyright 2009, Michael Lotz, mmlr@mlotz.ch.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
/*
|
||||
* Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de. 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>
|
||||
@ -10,6 +19,9 @@
|
||||
#include <OS.h>
|
||||
|
||||
|
||||
// #pragma mark - mutex
|
||||
|
||||
|
||||
status_t
|
||||
mutex_init(mutex *lock, const char *name)
|
||||
{
|
||||
@ -55,6 +67,9 @@ mutex_unlock(mutex *lock)
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - R/W lock
|
||||
|
||||
|
||||
typedef struct rw_lock_waiter {
|
||||
rw_lock_waiter * next;
|
||||
thread_id thread;
|
||||
@ -248,3 +263,65 @@ rw_lock_write_unlock(rw_lock *lock)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user