VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/java/src/nsThreadUtils.h@ 98262

Last change on this file since 98262 was 46649, checked in by vboxsync, 12 years ago

Forward ported r85941 and required build fixes (Main: Implemented new event queue to separate system's native event queue and our own. Also, XPCOM is not needed for handling our own events. On Windows this also fixes the system's queue quota limitation).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.0 KB
Line 
1/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* vim:set ts=2 sw=2 sts=2 et cindent: */
3/* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 *
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
10 *
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
15 *
16 * The Original Code is Mozilla code.
17 *
18 * The Initial Developer of the Original Code is Google Inc.
19 * Portions created by the Initial Developer are Copyright (C) 2006
20 * the Initial Developer. All Rights Reserved.
21 *
22 * Contributor(s):
23 * Darin Fisher <darin@meer.net>
24 *
25 * Alternatively, the contents of this file may be used under the terms of
26 * either the GNU General Public License Version 2 or later (the "GPL"), or
27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
36 *
37 * ***** END LICENSE BLOCK ***** */
38
39#ifndef nsThreadUtils_h__
40#define nsThreadUtils_h__
41
42
43#ifdef VBOX
44#include "nsIThread.h"
45
46inline already_AddRefed<nsIThread>
47do_GetMainThread() {
48 nsIThread *thread = nsnull;
49 nsIThread::GetMainThread(&thread);
50 return already_AddRefed<nsIThread>(thread);
51}
52
53#include "VBox/com/NativeEventQueue.h"
54
55inline already_AddRefed<nsIEventQueue> do_GetMainThreadQueue()
56{
57 com::NativeEventQueue* eq = com::NativeEventQueue::getMainEventQueue();
58 NS_ASSERTION(eq != nsnull, "Must be valid");
59 return eq->getIEventQueue();
60}
61
62#else
63#include "prthread.h"
64#include "prinrval.h"
65#include "nsIThreadManager.h"
66#include "nsIThread.h"
67#include "nsIRunnable.h"
68#include "nsStringGlue.h"
69#include "nsCOMPtr.h"
70
71
72// This is needed on some systems to prevent collisions between the symbols
73// appearing in xpcom_core and xpcomglue. It may be unnecessary in the future
74// with better toolchain support.
75#ifdef MOZILLA_INTERNAL_API
76# define NS_NewThread NS_NewThread_P
77# define NS_GetCurrentThread NS_GetCurrentThread_P
78# define NS_GetMainThread NS_GetMainThread_P
79# define NS_IsMainThread NS_IsMainThread_P
80# define NS_DispatchToCurrentThread NS_DispatchToCurrentThread_P
81# define NS_DispatchToMainThread NS_DispatchToMainThread_P
82# define NS_ProcessPendingEvents NS_ProcessPendingEvents_P
83# define NS_HasPendingEvents NS_HasPendingEvents_P
84# define NS_ProcessNextEvent NS_ProcessNextEvent_P
85#endif
86
87//-----------------------------------------------------------------------------
88// These methods are alternatives to the methods on nsIThreadManager, provided
89// for convenience.
90
91/**
92 * Create a new thread, and optionally provide an initial event for the thread.
93 *
94 * @param result
95 * The resulting nsIThread object.
96 * @param initialEvent
97 * The initial event to run on this thread. This parameter may be null.
98 *
99 * @returns NS_ERROR_INVALID_ARG
100 * Indicates that the given name is not unique.
101 */
102extern NS_COM_GLUE NS_METHOD
103NS_NewThread(nsIThread **result, nsIRunnable *initialEvent = nsnull);
104
105/**
106 * Get a reference to the current thread.
107 *
108 * @param result
109 * The resulting nsIThread object.
110 */
111extern NS_COM_GLUE NS_METHOD
112NS_GetCurrentThread(nsIThread **result);
113
114/**
115 * Get a reference to the main thread.
116 *
117 * @param result
118 * The resulting nsIThread object.
119 */
120extern NS_COM_GLUE NS_METHOD
121NS_GetMainThread(nsIThread **result);
122
123/**
124 * Test to see if the current thread is the main thread.
125 *
126 * @returns PR_TRUE if the current thread is the main thread, and PR_FALSE
127 * otherwise.
128 */
129extern NS_COM_GLUE NS_METHOD_(PRBool)
130NS_IsMainThread();
131
132/**
133 * Dispatch the given event to the current thread.
134 *
135 * @param event
136 * The event to dispatch.
137 *
138 * @returns NS_ERROR_INVALID_ARG
139 * If event is null.
140 */
141extern NS_COM_GLUE NS_METHOD
142NS_DispatchToCurrentThread(nsIRunnable *event);
143
144/**
145 * Dispatch the given event to the main thread.
146 *
147 * @param event
148 * The event to dispatch.
149 * @param dispatchFlags
150 * The flags to pass to the main thread's dispatch method.
151 *
152 * @returns NS_ERROR_INVALID_ARG
153 * If event is null.
154 */
155extern NS_COM_GLUE NS_METHOD
156NS_DispatchToMainThread(nsIRunnable *event,
157 PRUint32 dispatchFlags = NS_DISPATCH_NORMAL);
158
159#ifndef XPCOM_GLUE_AVOID_NSPR
160/**
161 * Process all pending events for the given thread before returning. This
162 * method simply calls ProcessNextEvent on the thread while HasPendingEvents
163 * continues to return true and the time spent in NS_ProcessPendingEvents
164 * does not exceed the given timeout value.
165 *
166 * @param thread
167 * The thread object for which to process pending events. If null, then
168 * events will be processed for the current thread.
169 * @param timeout
170 * The maximum number of milliseconds to spend processing pending events.
171 * Events are not pre-empted to honor this timeout. Rather, the timeout
172 * value is simply used to determine whether or not to process another event.
173 * Pass PR_INTERVAL_NO_TIMEOUT to specify no timeout.
174 */
175extern NS_COM_GLUE NS_METHOD
176NS_ProcessPendingEvents(nsIThread *thread,
177 PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT);
178#endif
179
180/**
181 * Shortcut for nsIThread::HasPendingEvents.
182 *
183 * It is an error to call this function when the given thread is not the
184 * current thread. This function will return PR_FALSE if called from some
185 * other thread.
186 *
187 * @param thread
188 * The current thread or null.
189 *
190 * @returns
191 * A boolean value that if "true" indicates that there are pending events
192 * in the current thread's event queue.
193 */
194extern NS_COM_GLUE PRBool
195NS_HasPendingEvents(nsIThread *thread = nsnull);
196
197/**
198 * Shortcut for nsIThread::ProcessNextEvent.
199 *
200 * It is an error to call this function when the given thread is not the
201 * current thread. This function will simply return PR_FALSE if called
202 * from some other thread.
203 *
204 * @param thread
205 * The current thread or null.
206 * @param mayWait
207 * A boolean parameter that if "true" indicates that the method may block
208 * the calling thread to wait for a pending event.
209 *
210 * @returns
211 * A boolean value that if "true" indicates that an event from the current
212 * thread's event queue was processed.
213 */
214extern NS_COM_GLUE PRBool
215NS_ProcessNextEvent(nsIThread *thread = nsnull, PRBool mayWait = PR_TRUE);
216
217//-----------------------------------------------------------------------------
218// Helpers that work with nsCOMPtr:
219
220inline already_AddRefed<nsIThread>
221do_GetCurrentThread() {
222 nsIThread *thread = nsnull;
223 NS_GetCurrentThread(&thread);
224 return already_AddRefed<nsIThread>(thread);
225}
226
227inline already_AddRefed<nsIThread>
228do_GetMainThread() {
229 nsIThread *thread = nsnull;
230 NS_GetMainThread(&thread);
231 return already_AddRefed<nsIThread>(thread);
232}
233
234//-----------------------------------------------------------------------------
235
236#ifdef MOZILLA_INTERNAL_API
237// Fast access to the current thread. Do not release the returned pointer! If
238// you want to use this pointer from some other thread, then you will need to
239// AddRef it. Otherwise, you should only consider this pointer valid from code
240// running on the current thread.
241extern NS_COM_GLUE nsIThread *NS_GetCurrentThread();
242#endif
243
244//-----------------------------------------------------------------------------
245
246#ifndef XPCOM_GLUE_AVOID_NSPR
247
248#undef IMETHOD_VISIBILITY
249#define IMETHOD_VISIBILITY NS_COM_GLUE
250
251// This class is designed to be subclassed.
252class NS_COM_GLUE nsRunnable : public nsIRunnable
253{
254public:
255 NS_DECL_ISUPPORTS
256 NS_DECL_NSIRUNNABLE
257
258 nsRunnable() {
259 }
260
261protected:
262 virtual ~nsRunnable() {
263 }
264};
265
266#undef IMETHOD_VISIBILITY
267#define IMETHOD_VISIBILITY NS_VISIBILITY_HIDDEN
268
269// An event that can be used to call a method on a class. The class type must
270// support reference counting.
271template <class T>
272class nsRunnableMethod : public nsRunnable
273{
274public:
275 typedef void (T::*Method)();
276
277 nsRunnableMethod(T *obj, Method method)
278 : mObj(obj), mMethod(method) {
279 NS_ADDREF(mObj);
280 }
281
282 NS_IMETHOD Run() {
283 (mObj->*mMethod)();
284 return NS_OK;
285 }
286
287private:
288 virtual ~nsRunnableMethod() {
289 NS_RELEASE(mObj);
290 }
291
292 T *mObj;
293 Method mMethod;
294};
295
296// Use this helper macro like so:
297//
298// nsCOMPtr<nsIRunnable> event =
299// NS_NEW_RUNNABLE_METHOD(MyClass, myObject, HandleEvent);
300// NS_DispatchToCurrentThread(event);
301//
302// Constraints:
303// - myObject must be of type MyClass
304// - MyClass must defined AddRef and Release methods
305//
306// NOTE: Attempts to make this a template function caused VC6 to barf :-(
307//
308#define NS_NEW_RUNNABLE_METHOD(class_, obj_, method_) \
309 new nsRunnableMethod<class_>(obj_, &class_::method_)
310
311#endif // XPCOM_GLUE_AVOID_NSPR
312
313// This class is designed to be used when you have an event class E that has a
314// pointer back to resource class R. If R goes away while E is still pending,
315// then it is important to "revoke" E so that it does not try use R after R has
316// been destroyed. nsRevocableEventPtr makes it easy for R to manage such
317// situations:
318//
319// class R;
320//
321// class E : public nsRunnable {
322// public:
323// void Revoke() {
324// mResource = nsnull;
325// }
326// private:
327// R *mResource;
328// };
329//
330// class R {
331// public:
332// void EventHandled() {
333// mEvent.Forget();
334// }
335// private:
336// nsRevocableEventPtr<E> mEvent;
337// };
338//
339// void R::PostEvent() {
340// // Make sure any pending event is revoked.
341// mEvent->Revoke();
342//
343// nsCOMPtr<nsIRunnable> event = new E();
344// if (NS_SUCCEEDED(NS_DispatchToCurrentThread(event))) {
345// // Keep pointer to event so we can revoke it.
346// mEvent = event;
347// }
348// }
349//
350// NS_IMETHODIMP E::Run() {
351// if (!mResource)
352// return NS_OK;
353// ...
354// mResource->EventHandled();
355// return NS_OK;
356// }
357//
358template <class T>
359class nsRevocableEventPtr {
360public:
361 nsRevocableEventPtr()
362 : mEvent(nsnull) {
363 }
364
365 ~nsRevocableEventPtr() {
366 Revoke();
367 }
368
369 const nsRevocableEventPtr& operator=(T *event) {
370 Revoke();
371 mEvent = event;
372 return *this;
373 }
374
375 void Revoke() {
376 if (mEvent) {
377 mEvent->Revoke();
378 mEvent = nsnull;
379 }
380 }
381
382 void Forget() {
383 mEvent = nsnull;
384 }
385
386 PRBool IsPending() {
387 return mEvent != nsnull;
388 }
389
390private:
391 // Not implemented
392 nsRevocableEventPtr(const nsRevocableEventPtr&);
393 nsRevocableEventPtr& operator=(const nsRevocableEventPtr&);
394
395 T *mEvent;
396};
397#endif
398
399#endif // nsThreadUtils_h__
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette