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