1 //------------------------------------------------------------------------------ 2 // Copyright (c) 2001-2002, OpenBeOS 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a 5 // copy of this software and associated documentation files (the "Software"), 6 // to deal in the Software without restriction, including without limitation 7 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 // and/or sell copies of the Software, and to permit persons to whom the 9 // Software is furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 // DEALINGS IN THE SOFTWARE. 21 // 22 // File Name: Looper.h 23 // Author(s): Erik Jaesler (erik@cgsoftware.com) 24 // DarkWyrm (bpmagic@columbus.rr.com) 25 // Description: BLooper class spawns a thread that runs a message loop. 26 //------------------------------------------------------------------------------ 27 28 #ifndef _LOOPER_H 29 #define _LOOPER_H 30 31 // Standard Includes ----------------------------------------------------------- 32 33 // System Includes ------------------------------------------------------------- 34 #include <BeBuild.h> 35 #include <Handler.h> 36 #include <List.h> 37 #include <OS.h> 38 39 // Project Includes ------------------------------------------------------------ 40 41 // Local Includes -------------------------------------------------------------- 42 43 // Local Defines --------------------------------------------------------------- 44 45 // Globals --------------------------------------------------------------------- 46 47 class BMessage; 48 class BMessageQueue; 49 namespace BPrivate { 50 class BLooperList; 51 } 52 struct _loop_data_; 53 54 // Port (Message Queue) Capacity ----------------------------------------------- 55 #define B_LOOPER_PORT_DEFAULT_CAPACITY 100 56 57 58 // BLooper class --------------------------------------------------------------- 59 class BLooper : public BHandler { 60 public: 61 BLooper(const char* name = NULL, 62 int32 priority = B_NORMAL_PRIORITY, 63 int32 port_capacity = B_LOOPER_PORT_DEFAULT_CAPACITY); 64 virtual ~BLooper(); 65 66 // Archiving 67 BLooper(BMessage* data); 68 static BArchivable* Instantiate(BMessage* data); 69 virtual status_t Archive(BMessage* data, bool deep = true) const; 70 71 // Message transmission 72 status_t PostMessage(uint32 command); 73 status_t PostMessage(BMessage* message); 74 status_t PostMessage(uint32 command, 75 BHandler* handler, 76 BHandler* reply_to = NULL); 77 status_t PostMessage(BMessage* message, 78 BHandler* handler, 79 BHandler* reply_to = NULL); 80 81 virtual void DispatchMessage(BMessage* message, BHandler* handler); 82 virtual void MessageReceived(BMessage* msg); 83 BMessage* CurrentMessage() const; 84 BMessage* DetachCurrentMessage(); 85 BMessageQueue* MessageQueue() const; 86 bool IsMessageWaiting() const; 87 88 // Message handlers 89 void AddHandler(BHandler* handler); 90 bool RemoveHandler(BHandler* handler); 91 int32 CountHandlers() const; 92 BHandler* HandlerAt(int32 index) const; 93 int32 IndexOf(BHandler* handler) const; 94 95 BHandler* PreferredHandler() const; 96 void SetPreferredHandler(BHandler* handler); 97 98 // Loop control 99 virtual thread_id Run(); 100 virtual void Quit(); 101 virtual bool QuitRequested(); 102 bool Lock(); 103 void Unlock(); 104 bool IsLocked() const; 105 status_t LockWithTimeout(bigtime_t timeout); 106 thread_id Thread() const; 107 team_id Team() const; 108 static BLooper* LooperForThread(thread_id tid); 109 110 // Loop debugging 111 thread_id LockingThread() const; 112 int32 CountLocks() const; 113 int32 CountLockRequests() const; 114 sem_id Sem() const; 115 116 // Scripting 117 virtual BHandler* ResolveSpecifier(BMessage* msg, 118 int32 index, 119 BMessage* specifier, 120 int32 form, 121 const char* property); 122 virtual status_t GetSupportedSuites(BMessage* data); 123 124 // Message filters (also see BHandler). 125 virtual void AddCommonFilter(BMessageFilter* filter); 126 virtual bool RemoveCommonFilter(BMessageFilter* filter); 127 virtual void SetCommonFilterList(BList* filters); 128 BList* CommonFilterList() const; 129 130 // Private or reserved --------------------------------------------------------- 131 virtual status_t Perform(perform_code d, void* arg); 132 133 protected: 134 // called from overridden task_looper 135 BMessage* MessageFromPort(bigtime_t = B_INFINITE_TIMEOUT); 136 137 private: 138 typedef BHandler _inherited; 139 friend class BWindow; 140 friend class BApplication; 141 friend class BMessenger; 142 friend class BView; 143 friend class BHandler; 144 friend class BPrivate::BLooperList; 145 friend port_id _get_looper_port_(const BLooper* ); 146 friend status_t _safe_get_server_token_(const BLooper* , int32* ); 147 friend team_id _find_cur_team_id_(); 148 149 virtual void _ReservedLooper1(); 150 virtual void _ReservedLooper2(); 151 virtual void _ReservedLooper3(); 152 virtual void _ReservedLooper4(); 153 virtual void _ReservedLooper5(); 154 virtual void _ReservedLooper6(); 155 156 BLooper(const BLooper&); 157 BLooper& operator=(const BLooper&); 158 159 BLooper(int32 priority, port_id port, const char* name); 160 161 status_t _PostMessage(BMessage* msg, 162 BHandler* handler, 163 BHandler* reply_to); 164 165 static status_t _Lock(BLooper* loop, 166 port_id port, 167 bigtime_t timeout); 168 static status_t _LockComplete(BLooper* loop, 169 int32 old, 170 thread_id this_tid, 171 sem_id sem, 172 bigtime_t timeout); 173 void InitData(); 174 void InitData(const char* name, int32 prio, int32 capacity); 175 void AddMessage(BMessage* msg); 176 void _AddMessagePriv(BMessage* msg); 177 static status_t _task0_(void* arg); 178 179 void* ReadRawFromPort(int32* code, 180 bigtime_t tout = B_INFINITE_TIMEOUT); 181 BMessage* ReadMessageFromPort(bigtime_t tout = B_INFINITE_TIMEOUT); 182 virtual BMessage* ConvertToMessage(void* raw, int32 code); 183 virtual void task_looper(); 184 void do_quit_requested(BMessage* msg); 185 bool AssertLocked() const; 186 BHandler* top_level_filter(BMessage* msg, BHandler* t); 187 BHandler* handler_only_filter(BMessage* msg, BHandler* t); 188 BHandler* apply_filters( BList* list, 189 BMessage* msg, 190 BHandler* target); 191 void check_lock(); 192 BHandler* resolve_specifier(BHandler* target, BMessage* msg); 193 void UnlockFully(); 194 195 static uint32 sLooperID; 196 static team_id sTeamID; 197 198 // DEPRECATED 199 static void AddLooper(BLooper* l); 200 static bool IsLooperValid(const BLooper* l); 201 static void RemoveLooper(BLooper* l); 202 static void GetLooperList(BList* list); 203 static BLooper* LooperForName(const char* name); 204 static BLooper* LooperForPort(port_id port); 205 206 uint32 fLooperID; 207 BMessageQueue* fQueue; 208 BMessage* fLastMessage; 209 port_id fMsgPort; 210 long fAtomicCount; 211 sem_id fLockSem; 212 long fOwnerCount; 213 thread_id fOwner; 214 thread_id fTaskID; 215 uint32 _unused1; 216 int32 fInitPriority; 217 BHandler* fPreferred; 218 BList fHandlers; 219 BList* fCommonFilters; 220 bool fTerminating; 221 bool fRunCalled; 222 thread_id fCachedPid; 223 size_t fCachedStack; 224 void* fMsgBuffer; 225 size_t fMsgBufferSize; 226 uint32 _reserved[6]; 227 }; 228 //------------------------------------------------------------------------------ 229 230 #endif // _LOOPER_H 231 232 /* 233 * $Log $ 234 * 235 * $Id $ 236 * 237 */ 238 239