xref: /haiku/src/system/libroot/os/locks/recursive_lock.cpp (revision a3e794ae459fec76826407f8ba8c94cd3535f128)
1 /*
2  * Copyright 2009, Michael Lotz, mmlr@mlotz.ch.
3  * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de.
4  * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
5  * Distributed under the terms of the MIT License.
6  *
7  * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
8  * Distributed under the terms of the NewOS License.
9  */
10 
11 
12 #include <locks.h>
13 
14 #include <OS.h>
15 
16 
17 // #pragma mark - recursive lock
18 
19 
20 int32
21 __recursive_lock_get_recursion(recursive_lock *lock)
22 {
23 	if (lock->holder == find_thread(NULL))
24 		return lock->recursion;
25 
26 	return -1;
27 }
28 
29 
30 void
31 __recursive_lock_init(recursive_lock *lock, const char *name)
32 {
33 	recursive_lock_init_etc(lock, name, 0);
34 }
35 
36 
37 void
38 __recursive_lock_init_etc(recursive_lock *lock, const char *name, uint32 flags)
39 {
40 	lock->holder = -1;
41 	lock->recursion = 0;
42 	mutex_init_etc(&lock->lock, name, flags);
43 }
44 
45 
46 void
47 __recursive_lock_destroy(recursive_lock *lock)
48 {
49 	if (lock == NULL)
50 		return;
51 
52 	mutex_destroy(&lock->lock);
53 }
54 
55 
56 status_t
57 __recursive_lock_lock(recursive_lock *lock)
58 {
59 	thread_id thread = find_thread(NULL);
60 
61 	if (thread != lock->holder) {
62 		mutex_lock(&lock->lock);
63 		lock->holder = thread;
64 	}
65 
66 	lock->recursion++;
67 	return B_OK;
68 }
69 
70 
71 void
72 __recursive_lock_unlock(recursive_lock *lock)
73 {
74 	if (find_thread(NULL) != lock->holder) {
75 		debugger("recursive_lock unlocked by non-holder thread!\n");
76 		return;
77 	}
78 
79 	if (--lock->recursion == 0) {
80 		lock->holder = -1;
81 		mutex_unlock(&lock->lock);
82 	}
83 }
84