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