//------------------------------------------------------------------------------ // Copyright (c) 2001-2002, OpenBeOS // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. // // File Name: Looper.h // Author(s): Erik Jaesler (erik@cgsoftware.com) // DarkWyrm (bpmagic@columbus.rr.com) // Description: BLooper class spawns a thread that runs a message loop. //------------------------------------------------------------------------------ #ifndef _LOOPER_H #define _LOOPER_H // Standard Includes ----------------------------------------------------------- // System Includes ------------------------------------------------------------- #include #include #include #include // Project Includes ------------------------------------------------------------ // Local Includes -------------------------------------------------------------- // Local Defines --------------------------------------------------------------- // Globals --------------------------------------------------------------------- class BMessage; class BMessageQueue; namespace BPrivate { class BLooperList; } struct _loop_data_; // Port (Message Queue) Capacity ----------------------------------------------- #define B_LOOPER_PORT_DEFAULT_CAPACITY 100 // BLooper class --------------------------------------------------------------- class BLooper : public BHandler { public: BLooper(const char* name = NULL, int32 priority = B_NORMAL_PRIORITY, int32 port_capacity = B_LOOPER_PORT_DEFAULT_CAPACITY); virtual ~BLooper(); // Archiving BLooper(BMessage* data); static BArchivable* Instantiate(BMessage* data); virtual status_t Archive(BMessage* data, bool deep = true) const; // Message transmission status_t PostMessage(uint32 command); status_t PostMessage(BMessage* message); status_t PostMessage(uint32 command, BHandler* handler, BHandler* reply_to = NULL); status_t PostMessage(BMessage* message, BHandler* handler, BHandler* reply_to = NULL); virtual void DispatchMessage(BMessage* message, BHandler* handler); virtual void MessageReceived(BMessage* msg); BMessage* CurrentMessage() const; BMessage* DetachCurrentMessage(); BMessageQueue* MessageQueue() const; bool IsMessageWaiting() const; // Message handlers void AddHandler(BHandler* handler); bool RemoveHandler(BHandler* handler); int32 CountHandlers() const; BHandler* HandlerAt(int32 index) const; int32 IndexOf(BHandler* handler) const; BHandler* PreferredHandler() const; void SetPreferredHandler(BHandler* handler); // Loop control virtual thread_id Run(); virtual void Quit(); virtual bool QuitRequested(); bool Lock(); void Unlock(); bool IsLocked() const; status_t LockWithTimeout(bigtime_t timeout); thread_id Thread() const; team_id Team() const; static BLooper* LooperForThread(thread_id tid); // Loop debugging thread_id LockingThread() const; int32 CountLocks() const; int32 CountLockRequests() const; sem_id Sem() const; // Scripting virtual BHandler* ResolveSpecifier(BMessage* msg, int32 index, BMessage* specifier, int32 form, const char* property); virtual status_t GetSupportedSuites(BMessage* data); // Message filters (also see BHandler). virtual void AddCommonFilter(BMessageFilter* filter); virtual bool RemoveCommonFilter(BMessageFilter* filter); virtual void SetCommonFilterList(BList* filters); BList* CommonFilterList() const; // Private or reserved --------------------------------------------------------- virtual status_t Perform(perform_code d, void* arg); protected: // called from overridden task_looper BMessage* MessageFromPort(bigtime_t = B_INFINITE_TIMEOUT); private: typedef BHandler _inherited; friend class BWindow; friend class BApplication; friend class BMessenger; friend class BView; friend class BHandler; friend class BPrivate::BLooperList; friend port_id _get_looper_port_(const BLooper* ); friend status_t _safe_get_server_token_(const BLooper* , int32* ); friend team_id _find_cur_team_id_(); virtual void _ReservedLooper1(); virtual void _ReservedLooper2(); virtual void _ReservedLooper3(); virtual void _ReservedLooper4(); virtual void _ReservedLooper5(); virtual void _ReservedLooper6(); BLooper(const BLooper&); BLooper& operator=(const BLooper&); BLooper(int32 priority, port_id port, const char* name); status_t _PostMessage(BMessage* msg, BHandler* handler, BHandler* reply_to); static status_t _Lock(BLooper* loop, port_id port, bigtime_t timeout); static status_t _LockComplete(BLooper* loop, int32 old, thread_id this_tid, sem_id sem, bigtime_t timeout); void InitData(); void InitData(const char* name, int32 prio, int32 capacity); void AddMessage(BMessage* msg); void _AddMessagePriv(BMessage* msg); static status_t _task0_(void* arg); void* ReadRawFromPort(int32* code, bigtime_t tout = B_INFINITE_TIMEOUT); BMessage* ReadMessageFromPort(bigtime_t tout = B_INFINITE_TIMEOUT); virtual BMessage* ConvertToMessage(void* raw, int32 code); virtual void task_looper(); void do_quit_requested(BMessage* msg); bool AssertLocked() const; BHandler* top_level_filter(BMessage* msg, BHandler* t); BHandler* handler_only_filter(BMessage* msg, BHandler* t); BHandler* apply_filters( BList* list, BMessage* msg, BHandler* target); void check_lock(); BHandler* resolve_specifier(BHandler* target, BMessage* msg); void UnlockFully(); static uint32 sLooperID; static team_id sTeamID; // DEPRECATED static void AddLooper(BLooper* l); static bool IsLooperValid(const BLooper* l); static void RemoveLooper(BLooper* l); static void GetLooperList(BList* list); static BLooper* LooperForName(const char* name); static BLooper* LooperForPort(port_id port); uint32 fLooperID; BMessageQueue* fQueue; BMessage* fLastMessage; port_id fMsgPort; long fAtomicCount; sem_id fLockSem; long fOwnerCount; thread_id fOwner; thread_id fTaskID; uint32 _unused1; int32 fInitPriority; BHandler* fPreferred; BList fHandlers; BList* fCommonFilters; bool fTerminating; bool fRunCalled; thread_id fCachedPid; size_t fCachedStack; void* fMsgBuffer; size_t fMsgBufferSize; uint32 _reserved[6]; }; //------------------------------------------------------------------------------ #endif // _LOOPER_H /* * $Log $ * * $Id $ * */