xref: /haiku/headers/build/os/app/Looper.h (revision 1d9d47fc72028bb71b5f232a877231e59cfe2438)
1 //------------------------------------------------------------------------------
2 //	Copyright (c) 2001-2002, OpenBeOS
3 //
4 //	Permission is hereby granted, free of charge, to any person obtaining a
5 //	copy of this software and associated documentation files (the "Software"),
6 //	to deal in the Software without restriction, including without limitation
7 //	the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 //	and/or sell copies of the Software, and to permit persons to whom the
9 //	Software is furnished to do so, subject to the following conditions:
10 //
11 //	The above copyright notice and this permission notice shall be included in
12 //	all copies or substantial portions of the Software.
13 //
14 //	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 //	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 //	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 //	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 //	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 //	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 //	DEALINGS IN THE SOFTWARE.
21 //
22 //	File Name:		Looper.h
23 //	Author(s):		Erik Jaesler (erik@cgsoftware.com)
24 //					DarkWyrm (bpmagic@columbus.rr.com)
25 //	Description:	BLooper class spawns a thread that runs a message loop.
26 //------------------------------------------------------------------------------
27 
28 #ifndef _LOOPER_H
29 #define _LOOPER_H
30 
31 // Standard Includes -----------------------------------------------------------
32 
33 // System Includes -------------------------------------------------------------
34 #include <BeBuild.h>
35 #include <Handler.h>
36 #include <List.h>
37 #include <OS.h>
38 
39 // Project Includes ------------------------------------------------------------
40 
41 // Local Includes --------------------------------------------------------------
42 
43 // Local Defines ---------------------------------------------------------------
44 
45 // Globals ---------------------------------------------------------------------
46 
47 class BMessage;
48 class BMessageQueue;
49 namespace BPrivate {
50 	class BLooperList;
51 }
52 struct _loop_data_;
53 
54 // Port (Message Queue) Capacity -----------------------------------------------
55 #define B_LOOPER_PORT_DEFAULT_CAPACITY	100
56 
57 
58 // BLooper class ---------------------------------------------------------------
59 class BLooper : public BHandler {
60 public:
61 						BLooper(const char* name = NULL,
62 								int32 priority = B_NORMAL_PRIORITY,
63 								int32 port_capacity = B_LOOPER_PORT_DEFAULT_CAPACITY);
64 virtual					~BLooper();
65 
66 // Archiving
67 						BLooper(BMessage* data);
68 static	BArchivable*	Instantiate(BMessage* data);
69 virtual	status_t		Archive(BMessage* data, bool deep = true) const;
70 
71 // Message transmission
72 		status_t		PostMessage(uint32 command);
73 		status_t		PostMessage(BMessage* message);
74 		status_t		PostMessage(uint32 command,
75 									BHandler* handler,
76 									BHandler* reply_to = NULL);
77 		status_t		PostMessage(BMessage* message,
78 									BHandler* handler,
79 									BHandler* reply_to = NULL);
80 
81 virtual	void			DispatchMessage(BMessage* message, BHandler* handler);
82 virtual	void			MessageReceived(BMessage* msg);
83 		BMessage*		CurrentMessage() const;
84 		BMessage*		DetachCurrentMessage();
85 		BMessageQueue*	MessageQueue() const;
86 		bool			IsMessageWaiting() const;
87 
88 // Message handlers
89 		void			AddHandler(BHandler* handler);
90 		bool			RemoveHandler(BHandler* handler);
91 		int32			CountHandlers() const;
92 		BHandler*		HandlerAt(int32 index) const;
93 		int32			IndexOf(BHandler* handler) const;
94 
95 		BHandler*		PreferredHandler() const;
96 		void			SetPreferredHandler(BHandler* handler);
97 
98 // Loop control
99 virtual	thread_id		Run();
100 virtual	void			Quit();
101 virtual	bool			QuitRequested();
102 		bool			Lock();
103 		void			Unlock();
104 		bool			IsLocked() const;
105 		status_t		LockWithTimeout(bigtime_t timeout);
106 		thread_id		Thread() const;
107 		team_id			Team() const;
108 static	BLooper*		LooperForThread(thread_id tid);
109 
110 // Loop debugging
111 		thread_id		LockingThread() const;
112 		int32			CountLocks() const;
113 		int32			CountLockRequests() const;
114 		sem_id			Sem() const;
115 
116 // Scripting
117 virtual BHandler*		ResolveSpecifier(BMessage* msg,
118 										int32 index,
119 										BMessage* specifier,
120 										int32 form,
121 										const char* property);
122 virtual status_t		GetSupportedSuites(BMessage* data);
123 
124 // Message filters (also see BHandler).
125 virtual	void			AddCommonFilter(BMessageFilter* filter);
126 virtual	bool			RemoveCommonFilter(BMessageFilter* filter);
127 virtual	void			SetCommonFilterList(BList* filters);
128 		BList*			CommonFilterList() const;
129 
130 // Private or reserved ---------------------------------------------------------
131 virtual status_t		Perform(perform_code d, void* arg);
132 
133 protected:
134 		// called from overridden task_looper
135 		BMessage*		MessageFromPort(bigtime_t = B_INFINITE_TIMEOUT);
136 
137 private:
138 	typedef BHandler _inherited;
139 	friend class BWindow;
140 	friend class BApplication;
141 	friend class BMessenger;
142 	friend class BView;
143 	friend class BHandler;
144 	friend class BPrivate::BLooperList;
145 	friend port_id _get_looper_port_(const BLooper* );
146 	friend status_t _safe_get_server_token_(const BLooper* , int32* );
147 	friend team_id	_find_cur_team_id_();
148 
149 virtual	void			_ReservedLooper1();
150 virtual	void			_ReservedLooper2();
151 virtual	void			_ReservedLooper3();
152 virtual	void			_ReservedLooper4();
153 virtual	void			_ReservedLooper5();
154 virtual	void			_ReservedLooper6();
155 
156 						BLooper(const BLooper&);
157 		BLooper&		operator=(const BLooper&);
158 
159 						BLooper(int32 priority, port_id port, const char* name);
160 
161 		status_t		_PostMessage(BMessage* msg,
162 									 BHandler* handler,
163 									 BHandler* reply_to);
164 
165 static	status_t		_Lock(BLooper* loop,
166 							  port_id port,
167 							  bigtime_t timeout);
168 static	status_t		_LockComplete(BLooper* loop,
169 									  int32 old,
170 									  thread_id this_tid,
171 									  sem_id sem,
172 									  bigtime_t timeout);
173 		void			InitData();
174 		void			InitData(const char* name, int32 prio, int32 capacity);
175 		void			AddMessage(BMessage* msg);
176 		void			_AddMessagePriv(BMessage* msg);
177 static	status_t		_task0_(void* arg);
178 
179 		void*			ReadRawFromPort(int32* code,
180 										bigtime_t tout = B_INFINITE_TIMEOUT);
181 		BMessage*		ReadMessageFromPort(bigtime_t tout = B_INFINITE_TIMEOUT);
182 virtual	BMessage*		ConvertToMessage(void* raw, int32 code);
183 virtual	void			task_looper();
184 		void			do_quit_requested(BMessage* msg);
185 		bool			AssertLocked() const;
186 		BHandler*		top_level_filter(BMessage* msg, BHandler* t);
187 		BHandler*		handler_only_filter(BMessage* msg, BHandler* t);
188 		BHandler*		apply_filters(	BList* list,
189 										BMessage* msg,
190 										BHandler* target);
191 		void			check_lock();
192 		BHandler*		resolve_specifier(BHandler* target, BMessage* msg);
193 		void			UnlockFully();
194 
195 static	uint32			sLooperID;
196 static	team_id			sTeamID;
197 
198 // DEPRECATED
199 static	void			AddLooper(BLooper* l);
200 static	bool			IsLooperValid(const BLooper* l);
201 static	void			RemoveLooper(BLooper* l);
202 static	void			GetLooperList(BList* list);
203 static	BLooper*		LooperForName(const char* name);
204 static	BLooper*		LooperForPort(port_id port);
205 
206 		uint32			fLooperID;
207 		BMessageQueue*	fQueue;
208 		BMessage*		fLastMessage;
209 		port_id			fMsgPort;
210 		long			fAtomicCount;
211 		sem_id			fLockSem;
212 		long			fOwnerCount;
213 		thread_id		fOwner;
214 		thread_id		fTaskID;
215 		uint32			_unused1;
216 		int32			fInitPriority;
217 		BHandler*		fPreferred;
218 		BList			fHandlers;
219 		BList*			fCommonFilters;
220 		bool			fTerminating;
221 		bool			fRunCalled;
222 		thread_id		fCachedPid;
223 		size_t			fCachedStack;
224 		void*			fMsgBuffer;
225 		size_t			fMsgBufferSize;
226 		uint32			_reserved[6];
227 };
228 //------------------------------------------------------------------------------
229 
230 #endif	// _LOOPER_H
231 
232 /*
233  * $Log $
234  *
235  * $Id  $
236  *
237  */
238 
239