xref: /haiku/src/system/libroot/os/locks/recursive_lock.cpp (revision 9563f44bfd75799f67201067483694e82b5779b9)
1 /*
2  * Copyright 2009, Michael Lotz, mmlr@mlotz.ch.
3  * Copyright 2008-2009, 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 status_t
31 recursive_lock_init(recursive_lock *lock, const char *name)
32 {
33 	lock->holder = -1;
34 	lock->recursion = 0;
35 	return mutex_init(&lock->lock, name != NULL ? name : "recursive lock");
36 }
37 
38 
39 void
40 recursive_lock_destroy(recursive_lock *lock)
41 {
42 	if (lock == NULL)
43 		return;
44 
45 	mutex_destroy(&lock->lock);
46 }
47 
48 
49 status_t
50 recursive_lock_lock(recursive_lock *lock)
51 {
52 	thread_id thread = find_thread(NULL);
53 
54 	if (thread != lock->holder) {
55 		mutex_lock(&lock->lock);
56 		lock->holder = thread;
57 	}
58 
59 	lock->recursion++;
60 	return B_OK;
61 }
62 
63 
64 void
65 recursive_lock_unlock(recursive_lock *lock)
66 {
67 	if (find_thread(NULL) != lock->holder) {
68 		debugger("recursive_lock unlocked by non-holder thread!\n");
69 		return;
70 	}
71 
72 	if (--lock->recursion == 0) {
73 		lock->holder = -1;
74 		mutex_unlock(&lock->lock);
75 	}
76 }
77 
78 
79 // #pragma mark - lazy recursive lock
80 
81 
82 int32
83 lazy_recursive_lock_get_recursion(lazy_recursive_lock *lock)
84 {
85 	if (lock->holder == find_thread(NULL))
86 		return lock->recursion;
87 
88 	return -1;
89 }
90 
91 
92 status_t
93 lazy_recursive_lock_init(lazy_recursive_lock *lock, const char *name)
94 {
95 	lock->holder = -1;
96 	lock->recursion = 0;
97 	return lazy_mutex_init(&lock->lock, name != NULL ? name : "recursive lock");
98 }
99 
100 
101 void
102 lazy_recursive_lock_destroy(lazy_recursive_lock *lock)
103 {
104 	if (lock == NULL)
105 		return;
106 
107 	lazy_mutex_destroy(&lock->lock);
108 }
109 
110 
111 status_t
112 lazy_recursive_lock_lock(lazy_recursive_lock *lock)
113 {
114 	thread_id thread = find_thread(NULL);
115 
116 	if (thread != lock->holder) {
117 		lazy_mutex_lock(&lock->lock);
118 		lock->holder = thread;
119 	}
120 
121 	lock->recursion++;
122 	return B_OK;
123 }
124 
125 
126 void
127 lazy_recursive_lock_unlock(lazy_recursive_lock *lock)
128 {
129 	if (find_thread(NULL) != lock->holder) {
130 		debugger("lazy_recursive_lock unlocked by non-holder thread!\n");
131 		return;
132 	}
133 
134 	if (--lock->recursion == 0) {
135 		lock->holder = -1;
136 		lazy_mutex_unlock(&lock->lock);
137 	}
138 }
139