xref: /haiku/headers/os/app/Looper.h (revision 9ecf9d1c1d4888d341a6eac72112c72d1ae3a4cb)
1 /*
2  * Copyright 2001-2006, 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 
18 class BMessage;
19 class BMessageQueue;
20 namespace BPrivate {
21 	class BLooperList;
22 }
23 
24 // Port (Message Queue) Capacity
25 #define B_LOOPER_PORT_DEFAULT_CAPACITY	100
26 
27 
28 class BLooper : public BHandler {
29 public:
30 							BLooper(const char* name = NULL,
31 								int32 priority = B_NORMAL_PRIORITY,
32 								int32 port_capacity = B_LOOPER_PORT_DEFAULT_CAPACITY);
33 	virtual					~BLooper();
34 
35 	// Archiving
36 							BLooper(BMessage* data);
37 	static	BArchivable*	Instantiate(BMessage* data);
38 	virtual	status_t		Archive(BMessage* data, bool deep = true) const;
39 
40 	// Message transmission
41 			status_t		PostMessage(uint32 command);
42 			status_t		PostMessage(BMessage* message);
43 			status_t		PostMessage(uint32 command, BHandler* handler,
44 								BHandler* reply_to = NULL);
45 			status_t		PostMessage(BMessage* message, BHandler* handler,
46 								BHandler* reply_to = NULL);
47 
48 	virtual	void			DispatchMessage(BMessage* message, BHandler* handler);
49 	virtual	void			MessageReceived(BMessage* msg);
50 			BMessage*		CurrentMessage() const;
51 			BMessage*		DetachCurrentMessage();
52 			BMessageQueue*	MessageQueue() const;
53 			bool			IsMessageWaiting() const;
54 
55 	// Message handlers
56 			void			AddHandler(BHandler* handler);
57 			bool			RemoveHandler(BHandler* handler);
58 			int32			CountHandlers() const;
59 			BHandler*		HandlerAt(int32 index) const;
60 			int32			IndexOf(BHandler* handler) const;
61 
62 			BHandler*		PreferredHandler() const;
63 			void			SetPreferredHandler(BHandler* handler);
64 
65 	// Loop control
66 	virtual	thread_id		Run();
67 	virtual	void			Quit();
68 	virtual	bool			QuitRequested();
69 			bool			Lock();
70 			void			Unlock();
71 			bool			IsLocked() const;
72 			status_t		LockWithTimeout(bigtime_t timeout);
73 			thread_id		Thread() const;
74 			team_id			Team() const;
75 	static	BLooper*		LooperForThread(thread_id tid);
76 
77 	// Loop debugging
78 			thread_id		LockingThread() const;
79 			int32			CountLocks() const;
80 			int32			CountLockRequests() const;
81 			sem_id			Sem() const;
82 
83 	// Scripting
84 	virtual BHandler*		ResolveSpecifier(BMessage* msg, int32 index,
85 								BMessage* specifier, int32 form,
86 								const char* property);
87 	virtual status_t		GetSupportedSuites(BMessage* data);
88 
89 	// Message filters (also see BHandler).
90 	virtual	void			AddCommonFilter(BMessageFilter* filter);
91 	virtual	bool			RemoveCommonFilter(BMessageFilter* filter);
92 	virtual	void			SetCommonFilterList(BList* filters);
93 			BList*			CommonFilterList() const;
94 
95 	// Private or reserved ---------------------------------------------------------
96 	virtual status_t		Perform(perform_code d, void* arg);
97 
98 protected:
99 		// called from overridden task_looper
100 			BMessage*		MessageFromPort(bigtime_t = B_INFINITE_TIMEOUT);
101 
102 private:
103 	typedef BHandler _inherited;
104 	friend class BWindow;
105 	friend class BApplication;
106 	friend class BMessenger;
107 	friend class BView;
108 	friend class BHandler;
109 	friend class BPrivate::BLooperList;
110 	friend port_id _get_looper_port_(const BLooper* );
111 	friend status_t _safe_get_server_token_(const BLooper* , int32* );
112 	friend team_id	_find_cur_team_id_();
113 
114 	virtual	void			_ReservedLooper1();
115 	virtual	void			_ReservedLooper2();
116 	virtual	void			_ReservedLooper3();
117 	virtual	void			_ReservedLooper4();
118 	virtual	void			_ReservedLooper5();
119 	virtual	void			_ReservedLooper6();
120 
121 							BLooper(const BLooper&);
122 			BLooper&		operator=(const BLooper&);
123 
124 							BLooper(int32 priority, port_id port,
125 								const char* name);
126 
127 			status_t		_PostMessage(BMessage* msg, BHandler* handler,
128 								BHandler* reply_to);
129 
130 	static	status_t		_Lock(BLooper* loop, port_id port,
131 								bigtime_t timeout);
132 	static	status_t		_LockComplete(BLooper* loop, int32 old,
133 								thread_id this_tid, sem_id sem,
134 								bigtime_t timeout);
135 			void			InitData();
136 			void			InitData(const char* name, int32 prio, int32 capacity);
137 			void			AddMessage(BMessage* msg);
138 			void			_AddMessagePriv(BMessage* msg);
139 	static	status_t		_task0_(void* arg);
140 
141 			void*			ReadRawFromPort(int32* code,
142 								bigtime_t tout = B_INFINITE_TIMEOUT);
143 			BMessage*		ReadMessageFromPort(bigtime_t tout = B_INFINITE_TIMEOUT);
144 	virtual	BMessage*		ConvertToMessage(void* raw, int32 code);
145 	virtual	void			task_looper();
146 			void			_QuitRequested(BMessage* msg);
147 			bool			AssertLocked() const;
148 			BHandler*		_TopLevelFilter(BMessage* msg, BHandler* target);
149 			BHandler*		_HandlerFilter(BMessage* msg, BHandler* target);
150 			BHandler*		_ApplyFilters(BList* list, BMessage* msg,
151 								BHandler* target);
152 			void			check_lock();
153 			BHandler*		resolve_specifier(BHandler* target, BMessage* msg);
154 			void			UnlockFully();
155 
156 	static	uint32			sLooperID;
157 	static	team_id			sTeamID;
158 
159 // DEPRECATED
160 	static	void			AddLooper(BLooper* l);
161 	static	bool			IsLooperValid(const BLooper* l);
162 	static	void			RemoveLooper(BLooper* l);
163 	static	void			GetLooperList(BList* list);
164 	static	BLooper*		LooperForName(const char* name);
165 	static	BLooper*		LooperForPort(port_id port);
166 
167 			uint32			fLooperID;
168 			BMessageQueue*	fQueue;
169 			BMessage*		fLastMessage;
170 			port_id			fMsgPort;
171 			long			fAtomicCount;
172 			sem_id			fLockSem;
173 			long			fOwnerCount;
174 			thread_id		fOwner;
175 			thread_id		fTaskID;
176 			uint32			_unused1;
177 			int32			fInitPriority;
178 			BHandler*		fPreferred;
179 			BList			fHandlers;
180 			BList*			fCommonFilters;
181 			bool			fTerminating;
182 			bool			fRunCalled;
183 			thread_id		fCachedPid;
184 			size_t			fCachedStack;
185 			void*			fMsgBuffer;
186 			size_t			fMsgBufferSize;
187 			uint32			_reserved[6];
188 };
189 
190 #endif	// _LOOPER_H
191