xref: /haiku/headers/os/app/Looper.h (revision ed24eb5ff12640d052171c6a7feba37fab8a75d1)
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 
18 class BMessage;
19 class BMessageQueue;
20 namespace BPrivate {
21 	class BDirectMessageTarget;
22 	class BLooperList;
23 }
24 
25 // Port (Message Queue) Capacity
26 #define B_LOOPER_PORT_DEFAULT_CAPACITY	200
27 
28 
29 class BLooper : public BHandler {
30 public:
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 			void			Loop();
73 	virtual	void			Quit();
74 	virtual	bool			QuitRequested();
75 			bool			Lock();
76 			void			Unlock();
77 			bool			IsLocked() const;
78 			status_t		LockWithTimeout(bigtime_t timeout);
79 			thread_id		Thread() const;
80 			team_id			Team() const;
81 	static	BLooper*		LooperForThread(thread_id thread);
82 
83 	// Loop debugging
84 			thread_id		LockingThread() const;
85 			int32			CountLocks() const;
86 			int32			CountLockRequests() const;
87 			sem_id			Sem() const;
88 
89 	// Scripting
90 	virtual BHandler*		ResolveSpecifier(BMessage* message, int32 index,
91 								BMessage* specifier, int32 what,
92 								const char* property);
93 	virtual status_t		GetSupportedSuites(BMessage* data);
94 
95 	// Message filters (also see BHandler).
96 	virtual	void			AddCommonFilter(BMessageFilter* filter);
97 	virtual	bool			RemoveCommonFilter(BMessageFilter* filter);
98 	virtual	void			SetCommonFilterList(BList* filters);
99 			BList*			CommonFilterList() const;
100 
101 	// Private or reserved
102 	virtual status_t		Perform(perform_code d, void* arg);
103 
104 protected:
105 		// called from overridden task_looper
106 			BMessage*		MessageFromPort(bigtime_t = B_INFINITE_TIMEOUT);
107 
108 private:
109 	typedef BHandler _inherited;
110 	friend class BWindow;
111 	friend class BApplication;
112 	friend class BMessenger;
113 	friend class BView;
114 	friend class BHandler;
115 	friend class ::BPrivate::BLooperList;
116 	friend port_id _get_looper_port_(const BLooper* );
117 
118 	virtual	void			_ReservedLooper1();
119 	virtual	void			_ReservedLooper2();
120 	virtual	void			_ReservedLooper3();
121 	virtual	void			_ReservedLooper4();
122 	virtual	void			_ReservedLooper5();
123 	virtual	void			_ReservedLooper6();
124 
125 							BLooper(const BLooper&);
126 			BLooper&		operator=(const BLooper&);
127 
128 							BLooper(int32 priority, port_id port,
129 								const char* name);
130 
131 			status_t		_PostMessage(BMessage* msg, BHandler* handler,
132 								BHandler* reply_to);
133 
134 	static	status_t		_Lock(BLooper* loop, port_id port,
135 								bigtime_t timeout);
136 	static	status_t		_LockComplete(BLooper* loop, int32 old,
137 								thread_id this_tid, sem_id sem,
138 								bigtime_t timeout);
139 			void			_InitData(const char* name, int32 priority,
140 								port_id port, int32 capacity);
141 			void			AddMessage(BMessage* msg);
142 			void			_AddMessagePriv(BMessage* msg);
143 	static	status_t		_task0_(void* arg);
144 
145 			void*			ReadRawFromPort(int32* code,
146 								bigtime_t timeout = B_INFINITE_TIMEOUT);
147 			BMessage*		ReadMessageFromPort(
148 								bigtime_t timeout = B_INFINITE_TIMEOUT);
149 	virtual	BMessage*		ConvertToMessage(void* raw, int32 code);
150 	virtual	void			task_looper();
151 			void			_QuitRequested(BMessage* msg);
152 			bool			AssertLocked() const;
153 			BHandler*		_TopLevelFilter(BMessage* msg, BHandler* target);
154 			BHandler*		_HandlerFilter(BMessage* msg, BHandler* target);
155 			BHandler*		_ApplyFilters(BList* list, BMessage* msg,
156 								BHandler* target);
157 			void			check_lock();
158 			BHandler*		resolve_specifier(BHandler* target, BMessage* msg);
159 			void			UnlockFully();
160 
161 			::BPrivate::BDirectMessageTarget* fDirectTarget;
162 			BMessage*		fLastMessage;
163 			port_id			fMsgPort;
164 			int32			fAtomicCount;
165 			sem_id			fLockSem;
166 			int32			fOwnerCount;
167 			thread_id		fOwner;
168 			thread_id		fThread;
169 			addr_t			fCachedStack;
170 			int32			fInitPriority;
171 			BHandler*		fPreferred;
172 			BList			fHandlers;
173 			BList*			fCommonFilters;
174 			bool			fTerminating;
175 			bool			fRunCalled;
176 			bool			fOwnsPort;
177 			uint32			_reserved[11];
178 };
179 
180 #endif	// _LOOPER_H
181