1 /* 2 * Copyright 2001-2015 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 BDirectMessageTarget; 22 class BLooperList; 23 } 24 25 // Port (Message Queue) Capacity 26 #define B_LOOPER_PORT_DEFAULT_CAPACITY 200 27 28 29 class BLooper : public BHandler { 30 public: 31 BLooper(const char* name = NULL, 32 int32 priority = B_NORMAL_PRIORITY, 33 int32 portCapacity 34 = B_LOOPER_PORT_DEFAULT_CAPACITY); 35 virtual ~BLooper(); 36 37 // Archiving 38 BLooper(BMessage* data); 39 static BArchivable* Instantiate(BMessage* data); 40 virtual status_t Archive(BMessage* data, bool deep = true) const; 41 42 // Message transmission 43 status_t PostMessage(uint32 command); 44 status_t PostMessage(BMessage* message); 45 status_t PostMessage(uint32 command, BHandler* handler, 46 BHandler* replyTo = NULL); 47 status_t PostMessage(BMessage* message, BHandler* handler, 48 BHandler* replyTo = NULL); 49 50 virtual void DispatchMessage(BMessage* message, 51 BHandler* handler); 52 virtual void MessageReceived(BMessage* message); 53 BMessage* CurrentMessage() const; 54 BMessage* DetachCurrentMessage(); 55 void DispatchExternalMessage(BMessage* message, 56 BHandler* handler, bool& _detached); 57 BMessageQueue* MessageQueue() const; 58 bool IsMessageWaiting() const; 59 60 // Message handlers 61 void AddHandler(BHandler* handler); 62 bool RemoveHandler(BHandler* handler); 63 int32 CountHandlers() const; 64 BHandler* HandlerAt(int32 index) const; 65 int32 IndexOf(BHandler* handler) const; 66 67 BHandler* PreferredHandler() const; 68 void SetPreferredHandler(BHandler* handler); 69 70 // Loop control 71 virtual thread_id Run(); 72 void Loop(); 73 virtual void Quit(); 74 virtual bool QuitRequested(); 75 bool Lock(); 76 void Unlock(); 77 bool IsLocked() const; 78 status_t LockWithTimeout(bigtime_t timeout); 79 thread_id Thread() const; 80 team_id Team() const; 81 static BLooper* LooperForThread(thread_id thread); 82 83 // Loop debugging 84 thread_id LockingThread() const; 85 int32 CountLocks() const; 86 int32 CountLockRequests() const; 87 sem_id Sem() const; 88 89 // Scripting 90 virtual BHandler* ResolveSpecifier(BMessage* message, int32 index, 91 BMessage* specifier, int32 what, 92 const char* property); 93 virtual status_t GetSupportedSuites(BMessage* data); 94 95 // Message filters (also see BHandler). 96 virtual void AddCommonFilter(BMessageFilter* filter); 97 virtual bool RemoveCommonFilter(BMessageFilter* filter); 98 virtual void SetCommonFilterList(BList* filters); 99 BList* CommonFilterList() const; 100 101 // Private or reserved 102 virtual status_t Perform(perform_code d, void* arg); 103 104 protected: 105 // called from overridden task_looper 106 BMessage* MessageFromPort(bigtime_t = B_INFINITE_TIMEOUT); 107 108 private: 109 typedef BHandler _inherited; 110 friend class BWindow; 111 friend class BApplication; 112 friend class BMessenger; 113 friend class BView; 114 friend class BHandler; 115 friend class ::BPrivate::BLooperList; 116 friend port_id _get_looper_port_(const BLooper* ); 117 118 virtual void _ReservedLooper1(); 119 virtual void _ReservedLooper2(); 120 virtual void _ReservedLooper3(); 121 virtual void _ReservedLooper4(); 122 virtual void _ReservedLooper5(); 123 virtual void _ReservedLooper6(); 124 125 BLooper(const BLooper&); 126 BLooper& operator=(const BLooper&); 127 128 BLooper(int32 priority, port_id port, 129 const char* name); 130 131 status_t _PostMessage(BMessage* msg, BHandler* handler, 132 BHandler* reply_to); 133 134 static status_t _Lock(BLooper* loop, port_id port, 135 bigtime_t timeout); 136 static status_t _LockComplete(BLooper* loop, int32 old, 137 thread_id this_tid, sem_id sem, 138 bigtime_t timeout); 139 void _InitData(const char* name, int32 priority, 140 port_id port, int32 capacity); 141 void AddMessage(BMessage* msg); 142 void _AddMessagePriv(BMessage* msg); 143 static status_t _task0_(void* arg); 144 145 void* ReadRawFromPort(int32* code, 146 bigtime_t timeout = B_INFINITE_TIMEOUT); 147 BMessage* ReadMessageFromPort( 148 bigtime_t timeout = B_INFINITE_TIMEOUT); 149 virtual BMessage* ConvertToMessage(void* raw, int32 code); 150 virtual void task_looper(); 151 void _QuitRequested(BMessage* msg); 152 bool AssertLocked() const; 153 BHandler* _TopLevelFilter(BMessage* msg, BHandler* target); 154 BHandler* _HandlerFilter(BMessage* msg, BHandler* target); 155 BHandler* _ApplyFilters(BList* list, BMessage* msg, 156 BHandler* target); 157 void check_lock(); 158 BHandler* resolve_specifier(BHandler* target, BMessage* msg); 159 void UnlockFully(); 160 161 ::BPrivate::BDirectMessageTarget* fDirectTarget; 162 BMessage* fLastMessage; 163 port_id fMsgPort; 164 int32 fAtomicCount; 165 sem_id fLockSem; 166 int32 fOwnerCount; 167 thread_id fOwner; 168 thread_id fThread; 169 addr_t fCachedStack; 170 int32 fInitPriority; 171 BHandler* fPreferred; 172 BList fHandlers; 173 BList* fCommonFilters; 174 bool fTerminating; 175 bool fRunCalled; 176 bool fOwnsPort; 177 uint32 _reserved[11]; 178 }; 179 180 #endif // _LOOPER_H 181