xref: /haiku/headers/os/app/Looper.h (revision eaad52e8d72af216e4b306cd34323e30bb976130)
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