1a6c9722dSAxel Dörfler /* 21480e5daSAxel Dörfler * Copyright 2001-2015 Haiku, Inc. All rights reserved. 3a6c9722dSAxel Dörfler * Distributed under the terms of the MIT License. 4a6c9722dSAxel Dörfler * 5a6c9722dSAxel Dörfler * Authors: 6be902ac4SJohn Scipione * Erik Jaesler, erik@cgsoftware.com 7a6c9722dSAxel Dörfler */ 852a38012Sejakowatz #ifndef _LOOPER_H 952a38012Sejakowatz #define _LOOPER_H 1052a38012Sejakowatz 1152a38012Sejakowatz 1252a38012Sejakowatz #include <BeBuild.h> 1352a38012Sejakowatz #include <Handler.h> 1452a38012Sejakowatz #include <List.h> 1552a38012Sejakowatz #include <OS.h> 1652a38012Sejakowatz 1752a38012Sejakowatz 1852a38012Sejakowatz class BMessage; 1952a38012Sejakowatz class BMessageQueue; 20abb57933Sejakowatz namespace BPrivate { 219dbe170aSAxel Dörfler class BDirectMessageTarget; 22abb57933Sejakowatz class BLooperList; 23abb57933Sejakowatz } 2452a38012Sejakowatz 25a6c9722dSAxel Dörfler // Port (Message Queue) Capacity 26f20a8750SAxel Dörfler #define B_LOOPER_PORT_DEFAULT_CAPACITY 200 2752a38012Sejakowatz 2852a38012Sejakowatz 2952a38012Sejakowatz class BLooper : public BHandler { 3052a38012Sejakowatz public: 3152a38012Sejakowatz BLooper(const char* name = NULL, 3252a38012Sejakowatz int32 priority = B_NORMAL_PRIORITY, 33be902ac4SJohn Scipione int32 portCapacity 34f20a8750SAxel Dörfler = B_LOOPER_PORT_DEFAULT_CAPACITY); 3552a38012Sejakowatz virtual ~BLooper(); 3652a38012Sejakowatz 3752a38012Sejakowatz // Archiving 3852a38012Sejakowatz BLooper(BMessage* data); 3952a38012Sejakowatz static BArchivable* Instantiate(BMessage* data); 4052a38012Sejakowatz virtual status_t Archive(BMessage* data, bool deep = true) const; 4152a38012Sejakowatz 4252a38012Sejakowatz // Message transmission 4352a38012Sejakowatz status_t PostMessage(uint32 command); 4452a38012Sejakowatz status_t PostMessage(BMessage* message); 45a6c9722dSAxel Dörfler status_t PostMessage(uint32 command, BHandler* handler, 46c01f349eSAxel Dörfler BHandler* replyTo = NULL); 47a6c9722dSAxel Dörfler status_t PostMessage(BMessage* message, BHandler* handler, 48c01f349eSAxel Dörfler BHandler* replyTo = NULL); 4952a38012Sejakowatz 50f20a8750SAxel Dörfler virtual void DispatchMessage(BMessage* message, 51f20a8750SAxel Dörfler BHandler* handler); 52f20a8750SAxel Dörfler virtual void MessageReceived(BMessage* message); 5352a38012Sejakowatz BMessage* CurrentMessage() const; 5452a38012Sejakowatz BMessage* DetachCurrentMessage(); 555d7f782dSIngo Weinhold void DispatchExternalMessage(BMessage* message, 565d7f782dSIngo Weinhold BHandler* handler, bool& _detached); 5752a38012Sejakowatz BMessageQueue* MessageQueue() const; 5852a38012Sejakowatz bool IsMessageWaiting() const; 5952a38012Sejakowatz 6052a38012Sejakowatz // Message handlers 6152a38012Sejakowatz void AddHandler(BHandler* handler); 6252a38012Sejakowatz bool RemoveHandler(BHandler* handler); 6352a38012Sejakowatz int32 CountHandlers() const; 6452a38012Sejakowatz BHandler* HandlerAt(int32 index) const; 6552a38012Sejakowatz int32 IndexOf(BHandler* handler) const; 6652a38012Sejakowatz 6752a38012Sejakowatz BHandler* PreferredHandler() const; 6852a38012Sejakowatz void SetPreferredHandler(BHandler* handler); 6952a38012Sejakowatz 7052a38012Sejakowatz // Loop control 7152a38012Sejakowatz virtual thread_id Run(); 72*151343ebSAdrien Destugues void Loop(); 7352a38012Sejakowatz virtual void Quit(); 7452a38012Sejakowatz virtual bool QuitRequested(); 7552a38012Sejakowatz bool Lock(); 7652a38012Sejakowatz void Unlock(); 7752a38012Sejakowatz bool IsLocked() const; 7852a38012Sejakowatz status_t LockWithTimeout(bigtime_t timeout); 7952a38012Sejakowatz thread_id Thread() const; 8052a38012Sejakowatz team_id Team() const; 81c01f349eSAxel Dörfler static BLooper* LooperForThread(thread_id thread); 8252a38012Sejakowatz 8352a38012Sejakowatz // Loop debugging 8452a38012Sejakowatz thread_id LockingThread() const; 8552a38012Sejakowatz int32 CountLocks() const; 8652a38012Sejakowatz int32 CountLockRequests() const; 8752a38012Sejakowatz sem_id Sem() const; 8852a38012Sejakowatz 8952a38012Sejakowatz // Scripting 90be902ac4SJohn Scipione virtual BHandler* ResolveSpecifier(BMessage* message, int32 index, 91be902ac4SJohn Scipione BMessage* specifier, int32 what, 9252a38012Sejakowatz const char* property); 9352a38012Sejakowatz virtual status_t GetSupportedSuites(BMessage* data); 9452a38012Sejakowatz 9552a38012Sejakowatz // Message filters (also see BHandler). 9652a38012Sejakowatz virtual void AddCommonFilter(BMessageFilter* filter); 9752a38012Sejakowatz virtual bool RemoveCommonFilter(BMessageFilter* filter); 9852a38012Sejakowatz virtual void SetCommonFilterList(BList* filters); 9952a38012Sejakowatz BList* CommonFilterList() const; 10052a38012Sejakowatz 101c01f349eSAxel Dörfler // Private or reserved 10252a38012Sejakowatz virtual status_t Perform(perform_code d, void* arg); 10352a38012Sejakowatz 10452a38012Sejakowatz protected: 10552a38012Sejakowatz // called from overridden task_looper 10652a38012Sejakowatz BMessage* MessageFromPort(bigtime_t = B_INFINITE_TIMEOUT); 10752a38012Sejakowatz 10852a38012Sejakowatz private: 10952a38012Sejakowatz typedef BHandler _inherited; 11052a38012Sejakowatz friend class BWindow; 11152a38012Sejakowatz friend class BApplication; 11252a38012Sejakowatz friend class BMessenger; 11352a38012Sejakowatz friend class BView; 11452a38012Sejakowatz friend class BHandler; 11518f5cd17SIngo Weinhold friend class ::BPrivate::BLooperList; 11652a38012Sejakowatz friend port_id _get_looper_port_(const BLooper* ); 11752a38012Sejakowatz 11852a38012Sejakowatz virtual void _ReservedLooper1(); 11952a38012Sejakowatz virtual void _ReservedLooper2(); 12052a38012Sejakowatz virtual void _ReservedLooper3(); 12152a38012Sejakowatz virtual void _ReservedLooper4(); 12252a38012Sejakowatz virtual void _ReservedLooper5(); 12352a38012Sejakowatz virtual void _ReservedLooper6(); 12452a38012Sejakowatz 12552a38012Sejakowatz BLooper(const BLooper&); 12652a38012Sejakowatz BLooper& operator=(const BLooper&); 12752a38012Sejakowatz 128a6c9722dSAxel Dörfler BLooper(int32 priority, port_id port, 129a6c9722dSAxel Dörfler const char* name); 13052a38012Sejakowatz 131a6c9722dSAxel Dörfler status_t _PostMessage(BMessage* msg, BHandler* handler, 13252a38012Sejakowatz BHandler* reply_to); 13352a38012Sejakowatz 134a6c9722dSAxel Dörfler static status_t _Lock(BLooper* loop, port_id port, 13552a38012Sejakowatz bigtime_t timeout); 136a6c9722dSAxel Dörfler static status_t _LockComplete(BLooper* loop, int32 old, 137a6c9722dSAxel Dörfler thread_id this_tid, sem_id sem, 13852a38012Sejakowatz bigtime_t timeout); 1391480e5daSAxel Dörfler void _InitData(const char* name, int32 priority, 1401480e5daSAxel Dörfler port_id port, int32 capacity); 14152a38012Sejakowatz void AddMessage(BMessage* msg); 14252a38012Sejakowatz void _AddMessagePriv(BMessage* msg); 14352a38012Sejakowatz static status_t _task0_(void* arg); 14452a38012Sejakowatz 14552a38012Sejakowatz void* ReadRawFromPort(int32* code, 1461480e5daSAxel Dörfler bigtime_t timeout = B_INFINITE_TIMEOUT); 1471480e5daSAxel Dörfler BMessage* ReadMessageFromPort( 1481480e5daSAxel Dörfler bigtime_t timeout = B_INFINITE_TIMEOUT); 14952a38012Sejakowatz virtual BMessage* ConvertToMessage(void* raw, int32 code); 15052a38012Sejakowatz virtual void task_looper(); 15114d02d22SAxel Dörfler void _QuitRequested(BMessage* msg); 15252a38012Sejakowatz bool AssertLocked() const; 15314d02d22SAxel Dörfler BHandler* _TopLevelFilter(BMessage* msg, BHandler* target); 15414d02d22SAxel Dörfler BHandler* _HandlerFilter(BMessage* msg, BHandler* target); 15514d02d22SAxel Dörfler BHandler* _ApplyFilters(BList* list, BMessage* msg, 15652a38012Sejakowatz BHandler* target); 15752a38012Sejakowatz void check_lock(); 15852a38012Sejakowatz BHandler* resolve_specifier(BHandler* target, BMessage* msg); 15952a38012Sejakowatz void UnlockFully(); 16052a38012Sejakowatz 16118f5cd17SIngo Weinhold ::BPrivate::BDirectMessageTarget* fDirectTarget; 16252a38012Sejakowatz BMessage* fLastMessage; 16352a38012Sejakowatz port_id fMsgPort; 164c01f349eSAxel Dörfler int32 fAtomicCount; 16552a38012Sejakowatz sem_id fLockSem; 166c01f349eSAxel Dörfler int32 fOwnerCount; 16752a38012Sejakowatz thread_id fOwner; 168c01f349eSAxel Dörfler thread_id fThread; 169eaad52e8SAxel Dörfler addr_t fCachedStack; 17052a38012Sejakowatz int32 fInitPriority; 17152a38012Sejakowatz BHandler* fPreferred; 17252a38012Sejakowatz BList fHandlers; 17352a38012Sejakowatz BList* fCommonFilters; 17452a38012Sejakowatz bool fTerminating; 17552a38012Sejakowatz bool fRunCalled; 176798ad3dbSAxel Dörfler bool fOwnsPort; 177eaad52e8SAxel Dörfler uint32 _reserved[11]; 17852a38012Sejakowatz }; 17952a38012Sejakowatz 18052a38012Sejakowatz #endif // _LOOPER_H 181