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 virtual void Quit(); 73 virtual bool QuitRequested(); 74 bool Lock(); 75 void Unlock(); 76 bool IsLocked() const; 77 status_t LockWithTimeout(bigtime_t timeout); 78 thread_id Thread() const; 79 team_id Team() const; 80 static BLooper* LooperForThread(thread_id thread); 81 82 // Loop debugging 83 thread_id LockingThread() const; 84 int32 CountLocks() const; 85 int32 CountLockRequests() const; 86 sem_id Sem() const; 87 88 // Scripting 89 virtual BHandler* ResolveSpecifier(BMessage* message, int32 index, 90 BMessage* specifier, int32 what, 91 const char* property); 92 virtual status_t GetSupportedSuites(BMessage* data); 93 94 // Message filters (also see BHandler). 95 virtual void AddCommonFilter(BMessageFilter* filter); 96 virtual bool RemoveCommonFilter(BMessageFilter* filter); 97 virtual void SetCommonFilterList(BList* filters); 98 BList* CommonFilterList() const; 99 100 // Private or reserved 101 virtual status_t Perform(perform_code d, void* arg); 102 103 protected: 104 // called from overridden task_looper 105 BMessage* MessageFromPort(bigtime_t = B_INFINITE_TIMEOUT); 106 107 private: 108 typedef BHandler _inherited; 109 friend class BWindow; 110 friend class BApplication; 111 friend class BMessenger; 112 friend class BView; 113 friend class BHandler; 114 friend class ::BPrivate::BLooperList; 115 friend port_id _get_looper_port_(const BLooper* ); 116 117 virtual void _ReservedLooper1(); 118 virtual void _ReservedLooper2(); 119 virtual void _ReservedLooper3(); 120 virtual void _ReservedLooper4(); 121 virtual void _ReservedLooper5(); 122 virtual void _ReservedLooper6(); 123 124 BLooper(const BLooper&); 125 BLooper& operator=(const BLooper&); 126 127 BLooper(int32 priority, port_id port, 128 const char* name); 129 130 status_t _PostMessage(BMessage* msg, BHandler* handler, 131 BHandler* reply_to); 132 133 static status_t _Lock(BLooper* loop, port_id port, 134 bigtime_t timeout); 135 static status_t _LockComplete(BLooper* loop, int32 old, 136 thread_id this_tid, sem_id sem, 137 bigtime_t timeout); 138 void _InitData(const char* name, int32 priority, 139 port_id port, int32 capacity); 140 void AddMessage(BMessage* msg); 141 void _AddMessagePriv(BMessage* msg); 142 static status_t _task0_(void* arg); 143 144 void* ReadRawFromPort(int32* code, 145 bigtime_t timeout = B_INFINITE_TIMEOUT); 146 BMessage* ReadMessageFromPort( 147 bigtime_t timeout = B_INFINITE_TIMEOUT); 148 virtual BMessage* ConvertToMessage(void* raw, int32 code); 149 virtual void task_looper(); 150 void _QuitRequested(BMessage* msg); 151 bool AssertLocked() const; 152 BHandler* _TopLevelFilter(BMessage* msg, BHandler* target); 153 BHandler* _HandlerFilter(BMessage* msg, BHandler* target); 154 BHandler* _ApplyFilters(BList* list, BMessage* msg, 155 BHandler* target); 156 void check_lock(); 157 BHandler* resolve_specifier(BHandler* target, BMessage* msg); 158 void UnlockFully(); 159 160 ::BPrivate::BDirectMessageTarget* fDirectTarget; 161 BMessage* fLastMessage; 162 port_id fMsgPort; 163 int32 fAtomicCount; 164 sem_id fLockSem; 165 int32 fOwnerCount; 166 thread_id fOwner; 167 thread_id fThread; 168 addr_t fCachedStack; 169 int32 fInitPriority; 170 BHandler* fPreferred; 171 BList fHandlers; 172 BList* fCommonFilters; 173 bool fTerminating; 174 bool fRunCalled; 175 bool fOwnsPort; 176 uint32 _reserved[11]; 177 }; 178 179 #endif // _LOOPER_H 180