Looper.h revision 798ad3db
1/*
2 * Copyright 2001-2015 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Erik Jaesler, erik@cgsoftware.com
7 */
8#ifndef _LOOPER_H
9#define _LOOPER_H
10
11
12#include <BeBuild.h>
13#include <Handler.h>
14#include <List.h>
15#include <OS.h>
16
17
18class BMessage;
19class BMessageQueue;
20namespace BPrivate {
21	class BDirectMessageTarget;
22	class BLooperList;
23}
24
25// Port (Message Queue) Capacity
26#define B_LOOPER_PORT_DEFAULT_CAPACITY	200
27
28
29class BLooper : public BHandler {
30public:
31							BLooper(const char* name = NULL,
32								int32 priority = B_NORMAL_PRIORITY,
33								int32 portCapacity
34									= B_LOOPER_PORT_DEFAULT_CAPACITY);
35	virtual					~BLooper();
36
37	// Archiving
38							BLooper(BMessage* data);
39	static	BArchivable*	Instantiate(BMessage* data);
40	virtual	status_t		Archive(BMessage* data, bool deep = true) const;
41
42	// Message transmission
43			status_t		PostMessage(uint32 command);
44			status_t		PostMessage(BMessage* message);
45			status_t		PostMessage(uint32 command, BHandler* handler,
46								BHandler* replyTo = NULL);
47			status_t		PostMessage(BMessage* message, BHandler* handler,
48								BHandler* replyTo = NULL);
49
50	virtual	void			DispatchMessage(BMessage* message,
51								BHandler* handler);
52	virtual	void			MessageReceived(BMessage* message);
53			BMessage*		CurrentMessage() const;
54			BMessage*		DetachCurrentMessage();
55			void			DispatchExternalMessage(BMessage* message,
56								BHandler* handler, bool& _detached);
57			BMessageQueue*	MessageQueue() const;
58			bool			IsMessageWaiting() const;
59
60	// Message handlers
61			void			AddHandler(BHandler* handler);
62			bool			RemoveHandler(BHandler* handler);
63			int32			CountHandlers() const;
64			BHandler*		HandlerAt(int32 index) const;
65			int32			IndexOf(BHandler* handler) const;
66
67			BHandler*		PreferredHandler() const;
68			void			SetPreferredHandler(BHandler* handler);
69
70	// Loop control
71	virtual	thread_id		Run();
72	virtual	void			Quit();
73	virtual	bool			QuitRequested();
74			bool			Lock();
75			void			Unlock();
76			bool			IsLocked() const;
77			status_t		LockWithTimeout(bigtime_t timeout);
78			thread_id		Thread() const;
79			team_id			Team() const;
80	static	BLooper*		LooperForThread(thread_id thread);
81
82	// Loop debugging
83			thread_id		LockingThread() const;
84			int32			CountLocks() const;
85			int32			CountLockRequests() const;
86			sem_id			Sem() const;
87
88	// Scripting
89	virtual BHandler*		ResolveSpecifier(BMessage* message, int32 index,
90								BMessage* specifier, int32 what,
91								const char* property);
92	virtual status_t		GetSupportedSuites(BMessage* data);
93
94	// Message filters (also see BHandler).
95	virtual	void			AddCommonFilter(BMessageFilter* filter);
96	virtual	bool			RemoveCommonFilter(BMessageFilter* filter);
97	virtual	void			SetCommonFilterList(BList* filters);
98			BList*			CommonFilterList() const;
99
100	// Private or reserved
101	virtual status_t		Perform(perform_code d, void* arg);
102
103protected:
104		// called from overridden task_looper
105			BMessage*		MessageFromPort(bigtime_t = B_INFINITE_TIMEOUT);
106
107private:
108	typedef BHandler _inherited;
109	friend class BWindow;
110	friend class BApplication;
111	friend class BMessenger;
112	friend class BView;
113	friend class BHandler;
114	friend class ::BPrivate::BLooperList;
115	friend port_id _get_looper_port_(const BLooper* );
116
117	virtual	void			_ReservedLooper1();
118	virtual	void			_ReservedLooper2();
119	virtual	void			_ReservedLooper3();
120	virtual	void			_ReservedLooper4();
121	virtual	void			_ReservedLooper5();
122	virtual	void			_ReservedLooper6();
123
124							BLooper(const BLooper&);
125			BLooper&		operator=(const BLooper&);
126
127							BLooper(int32 priority, port_id port,
128								const char* name);
129
130			status_t		_PostMessage(BMessage* msg, BHandler* handler,
131								BHandler* reply_to);
132
133	static	status_t		_Lock(BLooper* loop, port_id port,
134								bigtime_t timeout);
135	static	status_t		_LockComplete(BLooper* loop, int32 old,
136								thread_id this_tid, sem_id sem,
137								bigtime_t timeout);
138			void			_InitData(const char* name, int32 priority,
139								port_id port, int32 capacity);
140			void			AddMessage(BMessage* msg);
141			void			_AddMessagePriv(BMessage* msg);
142	static	status_t		_task0_(void* arg);
143
144			void*			ReadRawFromPort(int32* code,
145								bigtime_t timeout = B_INFINITE_TIMEOUT);
146			BMessage*		ReadMessageFromPort(
147								bigtime_t timeout = B_INFINITE_TIMEOUT);
148	virtual	BMessage*		ConvertToMessage(void* raw, int32 code);
149	virtual	void			task_looper();
150			void			_QuitRequested(BMessage* msg);
151			bool			AssertLocked() const;
152			BHandler*		_TopLevelFilter(BMessage* msg, BHandler* target);
153			BHandler*		_HandlerFilter(BMessage* msg, BHandler* target);
154			BHandler*		_ApplyFilters(BList* list, BMessage* msg,
155								BHandler* target);
156			void			check_lock();
157			BHandler*		resolve_specifier(BHandler* target, BMessage* msg);
158			void			UnlockFully();
159
160			::BPrivate::BDirectMessageTarget* fDirectTarget;
161			BMessage*		fLastMessage;
162			port_id			fMsgPort;
163			int32			fAtomicCount;
164			sem_id			fLockSem;
165			int32			fOwnerCount;
166			thread_id		fOwner;
167			thread_id		fThread;
168			addr_t			fCachedStack;
169			int32			fInitPriority;
170			BHandler*		fPreferred;
171			BList			fHandlers;
172			BList*			fCommonFilters;
173			bool			fTerminating;
174			bool			fRunCalled;
175			bool			fOwnsPort;
176			uint32			_reserved[11];
177};
178
179#endif	// _LOOPER_H
180