1 /* 2 * Copyright 2001-2006, Haiku Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Erik Jaesler (erik@cgsoftware.com) 7 */ 8 #ifndef _LOOPER_H 9 #define _LOOPER_H 10 11 12 #include <BeBuild.h> 13 #include <Handler.h> 14 #include <List.h> 15 #include <OS.h> 16 17 18 class BMessage; 19 class BMessageQueue; 20 namespace BPrivate { 21 class BLooperList; 22 } 23 24 // Port (Message Queue) Capacity 25 #define B_LOOPER_PORT_DEFAULT_CAPACITY 100 26 27 28 class BLooper : public BHandler { 29 public: 30 BLooper(const char* name = NULL, 31 int32 priority = B_NORMAL_PRIORITY, 32 int32 port_capacity = B_LOOPER_PORT_DEFAULT_CAPACITY); 33 virtual ~BLooper(); 34 35 // Archiving 36 BLooper(BMessage* data); 37 static BArchivable* Instantiate(BMessage* data); 38 virtual status_t Archive(BMessage* data, bool deep = true) const; 39 40 // Message transmission 41 status_t PostMessage(uint32 command); 42 status_t PostMessage(BMessage* message); 43 status_t PostMessage(uint32 command, BHandler* handler, 44 BHandler* reply_to = NULL); 45 status_t PostMessage(BMessage* message, BHandler* handler, 46 BHandler* reply_to = NULL); 47 48 virtual void DispatchMessage(BMessage* message, BHandler* handler); 49 virtual void MessageReceived(BMessage* msg); 50 BMessage* CurrentMessage() const; 51 BMessage* DetachCurrentMessage(); 52 BMessageQueue* MessageQueue() const; 53 bool IsMessageWaiting() const; 54 55 // Message handlers 56 void AddHandler(BHandler* handler); 57 bool RemoveHandler(BHandler* handler); 58 int32 CountHandlers() const; 59 BHandler* HandlerAt(int32 index) const; 60 int32 IndexOf(BHandler* handler) const; 61 62 BHandler* PreferredHandler() const; 63 void SetPreferredHandler(BHandler* handler); 64 65 // Loop control 66 virtual thread_id Run(); 67 virtual void Quit(); 68 virtual bool QuitRequested(); 69 bool Lock(); 70 void Unlock(); 71 bool IsLocked() const; 72 status_t LockWithTimeout(bigtime_t timeout); 73 thread_id Thread() const; 74 team_id Team() const; 75 static BLooper* LooperForThread(thread_id tid); 76 77 // Loop debugging 78 thread_id LockingThread() const; 79 int32 CountLocks() const; 80 int32 CountLockRequests() const; 81 sem_id Sem() const; 82 83 // Scripting 84 virtual BHandler* ResolveSpecifier(BMessage* msg, int32 index, 85 BMessage* specifier, int32 form, 86 const char* property); 87 virtual status_t GetSupportedSuites(BMessage* data); 88 89 // Message filters (also see BHandler). 90 virtual void AddCommonFilter(BMessageFilter* filter); 91 virtual bool RemoveCommonFilter(BMessageFilter* filter); 92 virtual void SetCommonFilterList(BList* filters); 93 BList* CommonFilterList() const; 94 95 // Private or reserved --------------------------------------------------------- 96 virtual status_t Perform(perform_code d, void* arg); 97 98 protected: 99 // called from overridden task_looper 100 BMessage* MessageFromPort(bigtime_t = B_INFINITE_TIMEOUT); 101 102 private: 103 typedef BHandler _inherited; 104 friend class BWindow; 105 friend class BApplication; 106 friend class BMessenger; 107 friend class BView; 108 friend class BHandler; 109 friend class BPrivate::BLooperList; 110 friend port_id _get_looper_port_(const BLooper* ); 111 friend status_t _safe_get_server_token_(const BLooper* , int32* ); 112 friend team_id _find_cur_team_id_(); 113 114 virtual void _ReservedLooper1(); 115 virtual void _ReservedLooper2(); 116 virtual void _ReservedLooper3(); 117 virtual void _ReservedLooper4(); 118 virtual void _ReservedLooper5(); 119 virtual void _ReservedLooper6(); 120 121 BLooper(const BLooper&); 122 BLooper& operator=(const BLooper&); 123 124 BLooper(int32 priority, port_id port, 125 const char* name); 126 127 status_t _PostMessage(BMessage* msg, BHandler* handler, 128 BHandler* reply_to); 129 130 static status_t _Lock(BLooper* loop, port_id port, 131 bigtime_t timeout); 132 static status_t _LockComplete(BLooper* loop, int32 old, 133 thread_id this_tid, sem_id sem, 134 bigtime_t timeout); 135 void InitData(); 136 void InitData(const char* name, int32 prio, int32 capacity); 137 void AddMessage(BMessage* msg); 138 void _AddMessagePriv(BMessage* msg); 139 static status_t _task0_(void* arg); 140 141 void* ReadRawFromPort(int32* code, 142 bigtime_t tout = B_INFINITE_TIMEOUT); 143 BMessage* ReadMessageFromPort(bigtime_t tout = B_INFINITE_TIMEOUT); 144 virtual BMessage* ConvertToMessage(void* raw, int32 code); 145 virtual void task_looper(); 146 void _QuitRequested(BMessage* msg); 147 bool AssertLocked() const; 148 BHandler* _TopLevelFilter(BMessage* msg, BHandler* target); 149 BHandler* _HandlerFilter(BMessage* msg, BHandler* target); 150 BHandler* _ApplyFilters(BList* list, BMessage* msg, 151 BHandler* target); 152 void check_lock(); 153 BHandler* resolve_specifier(BHandler* target, BMessage* msg); 154 void UnlockFully(); 155 156 static uint32 sLooperID; 157 static team_id sTeamID; 158 159 // DEPRECATED 160 static void AddLooper(BLooper* l); 161 static bool IsLooperValid(const BLooper* l); 162 static void RemoveLooper(BLooper* l); 163 static void GetLooperList(BList* list); 164 static BLooper* LooperForName(const char* name); 165 static BLooper* LooperForPort(port_id port); 166 167 uint32 fLooperID; 168 BMessageQueue* fQueue; 169 BMessage* fLastMessage; 170 port_id fMsgPort; 171 long fAtomicCount; 172 sem_id fLockSem; 173 long fOwnerCount; 174 thread_id fOwner; 175 thread_id fTaskID; 176 uint32 _unused1; 177 int32 fInitPriority; 178 BHandler* fPreferred; 179 BList fHandlers; 180 BList* fCommonFilters; 181 bool fTerminating; 182 bool fRunCalled; 183 thread_id fCachedPid; 184 size_t fCachedStack; 185 void* fMsgBuffer; 186 size_t fMsgBufferSize; 187 uint32 _reserved[6]; 188 }; 189 190 #endif // _LOOPER_H 191