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