xref: /haiku/src/system/libroot/os/locks/recursive_lock.cpp (revision b916156a835cd4f1c16990c33d69190014df77b7)
1258b34c5SIngo Weinhold /*
2258b34c5SIngo Weinhold  * Copyright 2009, Michael Lotz, mmlr@mlotz.ch.
3f7127458SIngo Weinhold  * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de.
4258b34c5SIngo Weinhold  * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
5258b34c5SIngo Weinhold  * Distributed under the terms of the MIT License.
6258b34c5SIngo Weinhold  *
7258b34c5SIngo Weinhold  * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
8258b34c5SIngo Weinhold  * Distributed under the terms of the NewOS License.
9258b34c5SIngo Weinhold  */
10258b34c5SIngo Weinhold 
11258b34c5SIngo Weinhold 
12258b34c5SIngo Weinhold #include <locks.h>
13258b34c5SIngo Weinhold 
14258b34c5SIngo Weinhold #include <OS.h>
15258b34c5SIngo Weinhold 
16258b34c5SIngo Weinhold 
17258b34c5SIngo Weinhold // #pragma mark - recursive lock
18258b34c5SIngo Weinhold 
19258b34c5SIngo Weinhold 
20258b34c5SIngo Weinhold int32
__recursive_lock_get_recursion(recursive_lock * lock)21*b916156aSJulian Harnath __recursive_lock_get_recursion(recursive_lock *lock)
22258b34c5SIngo Weinhold {
23258b34c5SIngo Weinhold 	if (lock->holder == find_thread(NULL))
24258b34c5SIngo Weinhold 		return lock->recursion;
25258b34c5SIngo Weinhold 
26258b34c5SIngo Weinhold 	return -1;
27258b34c5SIngo Weinhold }
28258b34c5SIngo Weinhold 
29258b34c5SIngo Weinhold 
30f7127458SIngo Weinhold void
__recursive_lock_init(recursive_lock * lock,const char * name)31*b916156aSJulian Harnath __recursive_lock_init(recursive_lock *lock, const char *name)
32258b34c5SIngo Weinhold {
33f7127458SIngo Weinhold 	recursive_lock_init_etc(lock, name, 0);
34f7127458SIngo Weinhold }
35f7127458SIngo Weinhold 
36f7127458SIngo Weinhold 
37f7127458SIngo Weinhold void
__recursive_lock_init_etc(recursive_lock * lock,const char * name,uint32 flags)38*b916156aSJulian Harnath __recursive_lock_init_etc(recursive_lock *lock, const char *name, uint32 flags)
39f7127458SIngo Weinhold {
40258b34c5SIngo Weinhold 	lock->holder = -1;
41258b34c5SIngo Weinhold 	lock->recursion = 0;
42f7127458SIngo Weinhold 	mutex_init_etc(&lock->lock, name, flags);
43258b34c5SIngo Weinhold }
44258b34c5SIngo Weinhold 
45258b34c5SIngo Weinhold 
46258b34c5SIngo Weinhold void
__recursive_lock_destroy(recursive_lock * lock)47*b916156aSJulian Harnath __recursive_lock_destroy(recursive_lock *lock)
48258b34c5SIngo Weinhold {
49258b34c5SIngo Weinhold 	if (lock == NULL)
50258b34c5SIngo Weinhold 		return;
51258b34c5SIngo Weinhold 
52258b34c5SIngo Weinhold 	mutex_destroy(&lock->lock);
53258b34c5SIngo Weinhold }
54258b34c5SIngo Weinhold 
55258b34c5SIngo Weinhold 
56258b34c5SIngo Weinhold status_t
__recursive_lock_lock(recursive_lock * lock)57*b916156aSJulian Harnath __recursive_lock_lock(recursive_lock *lock)
58258b34c5SIngo Weinhold {
59258b34c5SIngo Weinhold 	thread_id thread = find_thread(NULL);
60258b34c5SIngo Weinhold 
61258b34c5SIngo Weinhold 	if (thread != lock->holder) {
62258b34c5SIngo Weinhold 		mutex_lock(&lock->lock);
63258b34c5SIngo Weinhold 		lock->holder = thread;
64258b34c5SIngo Weinhold 	}
65258b34c5SIngo Weinhold 
66258b34c5SIngo Weinhold 	lock->recursion++;
67258b34c5SIngo Weinhold 	return B_OK;
68258b34c5SIngo Weinhold }
69258b34c5SIngo Weinhold 
70258b34c5SIngo Weinhold 
71258b34c5SIngo Weinhold void
__recursive_lock_unlock(recursive_lock * lock)72*b916156aSJulian Harnath __recursive_lock_unlock(recursive_lock *lock)
73258b34c5SIngo Weinhold {
74258b34c5SIngo Weinhold 	if (find_thread(NULL) != lock->holder) {
75258b34c5SIngo Weinhold 		debugger("recursive_lock unlocked by non-holder thread!\n");
76258b34c5SIngo Weinhold 		return;
77258b34c5SIngo Weinhold 	}
78258b34c5SIngo Weinhold 
79258b34c5SIngo Weinhold 	if (--lock->recursion == 0) {
80258b34c5SIngo Weinhold 		lock->holder = -1;
81258b34c5SIngo Weinhold 		mutex_unlock(&lock->lock);
82258b34c5SIngo Weinhold 	}
83258b34c5SIngo Weinhold }
84