1a6c9722dSAxel Dörfler /* 2c01f349eSAxel Dörfler * Copyright 2001-2007, Haiku Inc. All Rights Reserved. 3a6c9722dSAxel Dörfler * Distributed under the terms of the MIT License. 4a6c9722dSAxel Dörfler * 5a6c9722dSAxel Dörfler * Authors: 6a6c9722dSAxel Dörfler * 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 2652a38012Sejakowatz #define B_LOOPER_PORT_DEFAULT_CAPACITY 100 2752a38012Sejakowatz 2852a38012Sejakowatz 2952a38012Sejakowatz class BLooper : public BHandler { 3052a38012Sejakowatz public: 3152a38012Sejakowatz BLooper(const char* name = NULL, 3252a38012Sejakowatz int32 priority = B_NORMAL_PRIORITY, 3352a38012Sejakowatz int32 port_capacity = B_LOOPER_PORT_DEFAULT_CAPACITY); 3452a38012Sejakowatz virtual ~BLooper(); 3552a38012Sejakowatz 3652a38012Sejakowatz // Archiving 3752a38012Sejakowatz BLooper(BMessage* data); 3852a38012Sejakowatz static BArchivable* Instantiate(BMessage* data); 3952a38012Sejakowatz virtual status_t Archive(BMessage* data, bool deep = true) const; 4052a38012Sejakowatz 4152a38012Sejakowatz // Message transmission 4252a38012Sejakowatz status_t PostMessage(uint32 command); 4352a38012Sejakowatz status_t PostMessage(BMessage* message); 44a6c9722dSAxel Dörfler status_t PostMessage(uint32 command, BHandler* handler, 45c01f349eSAxel Dörfler BHandler* replyTo = NULL); 46a6c9722dSAxel Dörfler status_t PostMessage(BMessage* message, BHandler* handler, 47c01f349eSAxel Dörfler BHandler* replyTo = NULL); 4852a38012Sejakowatz 4952a38012Sejakowatz virtual void DispatchMessage(BMessage* message, BHandler* handler); 5052a38012Sejakowatz virtual void MessageReceived(BMessage* msg); 5152a38012Sejakowatz BMessage* CurrentMessage() const; 5252a38012Sejakowatz BMessage* DetachCurrentMessage(); 5352a38012Sejakowatz BMessageQueue* MessageQueue() const; 5452a38012Sejakowatz bool IsMessageWaiting() const; 5552a38012Sejakowatz 5652a38012Sejakowatz // Message handlers 5752a38012Sejakowatz void AddHandler(BHandler* handler); 5852a38012Sejakowatz bool RemoveHandler(BHandler* handler); 5952a38012Sejakowatz int32 CountHandlers() const; 6052a38012Sejakowatz BHandler* HandlerAt(int32 index) const; 6152a38012Sejakowatz int32 IndexOf(BHandler* handler) const; 6252a38012Sejakowatz 6352a38012Sejakowatz BHandler* PreferredHandler() const; 6452a38012Sejakowatz void SetPreferredHandler(BHandler* handler); 6552a38012Sejakowatz 6652a38012Sejakowatz // Loop control 6752a38012Sejakowatz virtual thread_id Run(); 6852a38012Sejakowatz virtual void Quit(); 6952a38012Sejakowatz virtual bool QuitRequested(); 7052a38012Sejakowatz bool Lock(); 7152a38012Sejakowatz void Unlock(); 7252a38012Sejakowatz bool IsLocked() const; 7352a38012Sejakowatz status_t LockWithTimeout(bigtime_t timeout); 7452a38012Sejakowatz thread_id Thread() const; 7552a38012Sejakowatz team_id Team() const; 76c01f349eSAxel Dörfler static BLooper* LooperForThread(thread_id thread); 7752a38012Sejakowatz 7852a38012Sejakowatz // Loop debugging 7952a38012Sejakowatz thread_id LockingThread() const; 8052a38012Sejakowatz int32 CountLocks() const; 8152a38012Sejakowatz int32 CountLockRequests() const; 8252a38012Sejakowatz sem_id Sem() const; 8352a38012Sejakowatz 8452a38012Sejakowatz // Scripting 85a6c9722dSAxel Dörfler virtual BHandler* ResolveSpecifier(BMessage* msg, int32 index, 86a6c9722dSAxel Dörfler BMessage* specifier, int32 form, 8752a38012Sejakowatz const char* property); 8852a38012Sejakowatz virtual status_t GetSupportedSuites(BMessage* data); 8952a38012Sejakowatz 9052a38012Sejakowatz // Message filters (also see BHandler). 9152a38012Sejakowatz virtual void AddCommonFilter(BMessageFilter* filter); 9252a38012Sejakowatz virtual bool RemoveCommonFilter(BMessageFilter* filter); 9352a38012Sejakowatz virtual void SetCommonFilterList(BList* filters); 9452a38012Sejakowatz BList* CommonFilterList() const; 9552a38012Sejakowatz 96c01f349eSAxel Dörfler // Private or reserved 9752a38012Sejakowatz virtual status_t Perform(perform_code d, void* arg); 9852a38012Sejakowatz 9952a38012Sejakowatz protected: 10052a38012Sejakowatz // called from overridden task_looper 10152a38012Sejakowatz BMessage* MessageFromPort(bigtime_t = B_INFINITE_TIMEOUT); 10252a38012Sejakowatz 10352a38012Sejakowatz private: 10452a38012Sejakowatz typedef BHandler _inherited; 10552a38012Sejakowatz friend class BWindow; 10652a38012Sejakowatz friend class BApplication; 10752a38012Sejakowatz friend class BMessenger; 10852a38012Sejakowatz friend class BView; 10952a38012Sejakowatz friend class BHandler; 110abb57933Sejakowatz friend class BPrivate::BLooperList; 11152a38012Sejakowatz friend port_id _get_looper_port_(const BLooper* ); 11252a38012Sejakowatz 11352a38012Sejakowatz virtual void _ReservedLooper1(); 11452a38012Sejakowatz virtual void _ReservedLooper2(); 11552a38012Sejakowatz virtual void _ReservedLooper3(); 11652a38012Sejakowatz virtual void _ReservedLooper4(); 11752a38012Sejakowatz virtual void _ReservedLooper5(); 11852a38012Sejakowatz virtual void _ReservedLooper6(); 11952a38012Sejakowatz 12052a38012Sejakowatz BLooper(const BLooper&); 12152a38012Sejakowatz BLooper& operator=(const BLooper&); 12252a38012Sejakowatz 123a6c9722dSAxel Dörfler BLooper(int32 priority, port_id port, 124a6c9722dSAxel Dörfler const char* name); 12552a38012Sejakowatz 126a6c9722dSAxel Dörfler status_t _PostMessage(BMessage* msg, BHandler* handler, 12752a38012Sejakowatz BHandler* reply_to); 12852a38012Sejakowatz 129a6c9722dSAxel Dörfler static status_t _Lock(BLooper* loop, port_id port, 13052a38012Sejakowatz bigtime_t timeout); 131a6c9722dSAxel Dörfler static status_t _LockComplete(BLooper* loop, int32 old, 132a6c9722dSAxel Dörfler thread_id this_tid, sem_id sem, 13352a38012Sejakowatz bigtime_t timeout); 134c01f349eSAxel Dörfler void _InitData(const char* name, int32 priority, int32 capacity); 13552a38012Sejakowatz void AddMessage(BMessage* msg); 13652a38012Sejakowatz void _AddMessagePriv(BMessage* msg); 13752a38012Sejakowatz static status_t _task0_(void* arg); 13852a38012Sejakowatz 13952a38012Sejakowatz void* ReadRawFromPort(int32* code, 14052a38012Sejakowatz bigtime_t tout = B_INFINITE_TIMEOUT); 14152a38012Sejakowatz BMessage* ReadMessageFromPort(bigtime_t tout = B_INFINITE_TIMEOUT); 14252a38012Sejakowatz virtual BMessage* ConvertToMessage(void* raw, int32 code); 14352a38012Sejakowatz virtual void task_looper(); 14414d02d22SAxel Dörfler void _QuitRequested(BMessage* msg); 14552a38012Sejakowatz bool AssertLocked() const; 14614d02d22SAxel Dörfler BHandler* _TopLevelFilter(BMessage* msg, BHandler* target); 14714d02d22SAxel Dörfler BHandler* _HandlerFilter(BMessage* msg, BHandler* target); 14814d02d22SAxel Dörfler BHandler* _ApplyFilters(BList* list, BMessage* msg, 14952a38012Sejakowatz BHandler* target); 15052a38012Sejakowatz void check_lock(); 15152a38012Sejakowatz BHandler* resolve_specifier(BHandler* target, BMessage* msg); 15252a38012Sejakowatz void UnlockFully(); 15352a38012Sejakowatz 1549dbe170aSAxel Dörfler BPrivate::BDirectMessageTarget* fDirectTarget; 15552a38012Sejakowatz BMessage* fLastMessage; 15652a38012Sejakowatz port_id fMsgPort; 157c01f349eSAxel Dörfler int32 fAtomicCount; 15852a38012Sejakowatz sem_id fLockSem; 159c01f349eSAxel Dörfler int32 fOwnerCount; 16052a38012Sejakowatz thread_id fOwner; 161c01f349eSAxel Dörfler thread_id fThread; 162*eaad52e8SAxel Dörfler addr_t fCachedStack; 16352a38012Sejakowatz int32 fInitPriority; 16452a38012Sejakowatz BHandler* fPreferred; 16552a38012Sejakowatz BList fHandlers; 16652a38012Sejakowatz BList* fCommonFilters; 16752a38012Sejakowatz bool fTerminating; 16852a38012Sejakowatz bool fRunCalled; 169*eaad52e8SAxel Dörfler uint32 _reserved[11]; 17052a38012Sejakowatz }; 17152a38012Sejakowatz 17252a38012Sejakowatz #endif // _LOOPER_H 173