1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsIThread.idl"
interface nsIThreadObserver;
interface nsIThreadEventFilter;
/**
* The XPCOM thread object implements this interface, which allows a consumer
* to observe dispatch activity on the thread.
*/
[scriptable, uuid(504e9e1f-70e1-4f33-a785-5840a4680414)]
interface nsIThreadInternal : nsIThread
{
/**
* Get/set the current thread observer (may be null). This attribute may be
* read from any thread, but must only be set on the thread corresponding to
* this thread object. The observer will be released on the thread
* corresponding to this thread object after all other events have been
* processed during a call to Shutdown.
*/
attribute nsIThreadObserver observer;
/**
* The current recursion depth, 0 when no events are running, 1 when a single
* event is running, and higher when nested events are running. Must only be
* called on the target thread.
*/
readonly attribute unsigned long recursionDepth;
/**
* Add an observer that will *only* receive onProcessNextEvent and
* afterProcessNextEvent callbacks. Always called on the target thread, and
* the implementation does not have to be threadsafe. Order of callbacks is
* not guaranteed (i.e. afterProcessNextEvent may be called first depending on
* whether or not the observer is added in a nested loop). Holds a strong ref.
*/
void addObserver(in nsIThreadObserver observer);
/**
* Remove an observer added via the addObserver call. Once removed the
* observer will never be called again by the thread.
*/
void removeObserver(in nsIThreadObserver observer);
};
/**
* This interface provides the observer with hooks to implement a layered
* event queue. For example, it is possible to overlay processing events
* for a GUI toolkit on top of the events for a thread:
*
* var NativeQueue;
* Observer = {
* onDispatchedEvent(thread) {
* NativeQueue.signal();
* }
* onProcessNextEvent(thread, mayWait, recursionDepth) {
* if (NativeQueue.hasNextEvent())
* NativeQueue.processNextEvent();
* while (mayWait && !thread.hasPendingEvent()) {
* NativeQueue.wait();
* NativeQueue.processNextEvent();
* }
* }
* };
*
* NOTE: The implementation of this interface must be threadsafe.
*
* NOTE: It is valid to change the thread's observer during a call to an
* observer method.
*
* NOTE: Will be split into two interfaces soon: one for onProcessNextEvent and
* afterProcessNextEvent, then another that inherits the first and adds
* onDispatchedEvent.
*/
[scriptable, uuid(81D0B509-F198-4417-8020-08EB4271491F)]
interface nsIThreadObserver : nsISupports
{
/**
* This method is called after an event has been dispatched to the thread.
* This method may be called from any thread.
*
* @param thread
* The thread where the event is being dispatched.
*/
void onDispatchedEvent(in nsIThreadInternal thread);
/**
* This method is called (from nsIThread::ProcessNextEvent) before an event
* is processed. This method is only called on the target thread.
*
* @param thread
* The thread being asked to process another event.
* @param mayWait
* Indicates whether or not the method is allowed to block the calling
* thread. For example, this parameter is false during thread shutdown.
* @param recursionDepth
* Indicates the number of calls to ProcessNextEvent on the call stack in
* addition to the current call.
*/
void onProcessNextEvent(in nsIThreadInternal thread, in boolean mayWait,
in unsigned long recursionDepth);
/**
* This method is called (from nsIThread::ProcessNextEvent) after an event
* is processed. This method is only called on the target thread.
*
* @param thread
* The thread that processed another event.
* @param recursionDepth
* Indicates the number of calls to ProcessNextEvent on the call stack in
* addition to the current call.
*/
void afterProcessNextEvent(in nsIThreadInternal thread,
in unsigned long recursionDepth);
};
|