xref: /haiku/headers/private/kernel/condition_variable.h (revision 71452e98334eaac603bf542d159e24788a46bebb)
1 /*
2  * Copyright 2007-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef _KERNEL_CONDITION_VARIABLE_H
6 #define _KERNEL_CONDITION_VARIABLE_H
7 
8 
9 #include <OS.h>
10 
11 #include <debug.h>
12 
13 #ifdef __cplusplus
14 
15 #include <util/DoublyLinkedList.h>
16 #include <util/OpenHashTable.h>
17 
18 
19 struct ConditionVariable;
20 
21 
22 struct ConditionVariableEntry
23 	: DoublyLinkedListLinkImpl<ConditionVariableEntry> {
24 public:
25 #if KDEBUG
26 	inline						ConditionVariableEntry();
27 	inline						~ConditionVariableEntry();
28 #endif
29 
30 			bool				Add(const void* object);
31 			status_t			Wait(uint32 flags = 0, bigtime_t timeout = 0);
32 			status_t			Wait(const void* object, uint32 flags = 0,
33 									bigtime_t timeout = 0);
34 
35 	inline	status_t			WaitStatus() const { return fWaitStatus; }
36 
37 	inline	ConditionVariable*	Variable() const { return fVariable; }
38 
39 private:
40 	inline	void				AddToVariable(ConditionVariable* variable);
41 
42 private:
43 			ConditionVariable*	fVariable;
44 			Thread*				fThread;
45 			status_t			fWaitStatus;
46 
47 			friend struct ConditionVariable;
48 };
49 
50 
51 struct ConditionVariable {
52 public:
53 			void				Init(const void* object,
54 									const char* objectType);
55 									// for anonymous (unpublished) cvars
56 
57 			void				Publish(const void* object,
58 									const char* objectType);
59 			void				Unpublish();
60 
61 	inline	void				NotifyOne(status_t result = B_OK);
62 	inline	void				NotifyAll(status_t result = B_OK);
63 
64 	static	void				NotifyOne(const void* object, status_t result);
65 	static	void				NotifyAll(const void* object, status_t result);
66 									// (both methods) caller must ensure that
67 									// the variable is not unpublished
68 									// concurrently
69 
70 			void				Add(ConditionVariableEntry* entry);
71 
72 			status_t			Wait(uint32 flags = 0, bigtime_t timeout = 0);
73 									// all-in one, i.e. doesn't need a
74 									// ConditionVariableEntry
75 
76 			const void*			Object() const		{ return fObject; }
77 			const char*			ObjectType() const	{ return fObjectType; }
78 
79 	static	void				ListAll();
80 			void				Dump() const;
81 
82 private:
83 			void				_Notify(bool all, status_t result);
84 			void				_NotifyLocked(bool all, status_t result);
85 
86 protected:
87 			typedef DoublyLinkedList<ConditionVariableEntry> EntryList;
88 
89 			const void*			fObject;
90 			const char*			fObjectType;
91 			EntryList			fEntries;
92 			ConditionVariable*	fNext;
93 
94 			friend struct ConditionVariableEntry;
95 			friend struct ConditionVariableHashDefinition;
96 };
97 
98 
99 #if KDEBUG
100 
101 inline
102 ConditionVariableEntry::ConditionVariableEntry()
103 	: fVariable(NULL)
104 {
105 }
106 
107 inline
108 ConditionVariableEntry::~ConditionVariableEntry()
109 {
110 	if (fVariable != NULL) {
111 		panic("Destroying condition variable entry %p, but it's still "
112 			"attached to variable %p\n", this, fVariable);
113 	}
114 }
115 
116 #endif
117 
118 
119 inline void
120 ConditionVariable::NotifyOne(status_t result)
121 {
122 	_Notify(false, result);
123 }
124 
125 
126 inline void
127 ConditionVariable::NotifyAll(status_t result)
128 {
129 	_Notify(true, result);
130 }
131 
132 
133 extern "C" {
134 #endif	// __cplusplus
135 
136 extern void condition_variable_init();
137 
138 #ifdef __cplusplus
139 }	// extern "C"
140 #endif
141 
142 #endif	/* _KERNEL_CONDITION_VARIABLE_H */
143