summaryrefslogtreecommitdiffstats
path: root/xpcom/threads/nsIThreadManager.idl
blob: 2c5de409fe44a2663195da1bdb1d99090449e9c2 (plain)
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/* -*- 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 "nsISupports.idl"

[ptr] native PRThread(PRThread);
      native ThreadCreationOptions(nsIThreadManager::ThreadCreationOptions);

interface nsIEventTarget;
interface nsIRunnable;
interface nsIThread;

%{ C++
#include "mozilla/Maybe.h"
%}

[scriptable, function, uuid(039a227d-0cb7-44a5-a8f9-dbb7071979f2)]
interface nsINestedEventLoopCondition : nsISupports
{
  /**
   * Returns true if the current nested event loop should stop spinning.
   */
  boolean isDone();
};

/**
 * An interface for creating and locating nsIThread instances.
 */
[scriptable, builtinclass, uuid(1be89eca-e2f7-453b-8d38-c11ba247f6f3)]
interface nsIThreadManager : nsISupports
{
  /**
   * Default number of bytes reserved for a thread's stack, if no stack size
   * is specified in newThread().
   *
   * Defaults can be a little overzealous for many platforms.
   *
   * On Linux and OS X, for instance, the default thread stack size is whatever
   * getrlimit(RLIMIT_STACK) returns, which is often set at 8MB. Or, on Linux,
   * if the stack size is unlimited, we fall back to 2MB. This causes particular
   * problems on Linux, which allocates 2MB huge VM pages, and will often
   * immediately allocate them for any stacks which are 2MB or larger.
   *
   * The default on Windows is 1MB, which is a little more reasonable. But the
   * vast majority of our threads don't need anywhere near that much space.
   *
   * ASan, TSan and non-opt builds, however, often need a bit more, so give
   * them the platform default.
   */
%{C++
#if defined(MOZ_ASAN) || defined(MOZ_TSAN) || !defined(__OPTIMIZE__)
  static constexpr uint32_t DEFAULT_STACK_SIZE = 0;
#else
  static constexpr uint32_t DEFAULT_STACK_SIZE = 256 * 1024;
#endif

  static const uint32_t kThreadPoolStackSize = DEFAULT_STACK_SIZE;

  struct ThreadCreationOptions {
    // The size in bytes to reserve for the thread's stack. A value of `0` means
    // to use the platform default.
    uint32_t stackSize = nsIThreadManager::DEFAULT_STACK_SIZE;

    // If set to `true`, any attempts to dispatch runnables to this thread
    // without `DISPATCH_IGNORE_BLOCK_DISPATCH` will fail.
    //
    // This is intended to be used for threads which are expected to generally
    // only service a single runnable (other than thread lifecycle runnables),
    // and perform their own event dispatching internaly, such as thread pool
    // threads or the timer thread.
    bool blockDispatch = false;

    // (Windows-only) Whether the thread should have a MessageLoop capable of
    // processing native UI events. Defaults to false.
    bool isUiThread = false;

    // If set, long task markers will be collected for tasks
    // longer than longTaskLength ms when profiling is enabled.
    // See https://www.w3.org/TR/longtasks
    mozilla::Maybe<uint32_t> longTaskLength;
  };
%}

  /**
   * Create a new thread (a global, user PRThread) with the specified name.
   *
   * @param name
   *   The name of the thread. If it is empty the thread will not be named.
   * @param options
   *   Configuration options for the newly created thread.
   *
   * @returns
   *   The newly created nsIThread object.
   */
  [noscript] nsIThread newNamedThread(in ACString name, in ThreadCreationOptions options);

  /**
   * Get the main thread.
   */
  readonly attribute nsIThread mainThread;

  /**
   * Get the current thread.  If the calling thread does not already have a
   * nsIThread associated with it, then a new nsIThread will be created and
   * associated with the current PRThread.
   */
  readonly attribute nsIThread currentThread;

  /**
   * This queues a runnable to the main thread. It's a shortcut for JS callers
   * to be used instead of
   *   .mainThread.dispatch(runnable, Ci.nsIEventTarget.DISPATCH_NORMAL);
   * or
   *   .currentThread.dispatch(runnable, Ci.nsIEventTarget.DISPATCH_NORMAL);
   * C++ callers should instead use NS_DispatchToMainThread.
   */
  [optional_argc]
  void dispatchToMainThread(in nsIRunnable event, [optional] in uint32_t priority);

  /**
   * Similar to dispatchToMainThread, but wraps the event with extra
   * runnable that allocates nsAutoMicroTask.
   */
  [optional_argc]
  void dispatchToMainThreadWithMicroTask(in nsIRunnable event, [optional] in uint32_t priority);

  /**
   * This queues a runnable to the main thread's idle queue.
   *
   * @param event
   *   The event to dispatch.
   * @param timeout
   *   The time in milliseconds until this event should be moved from the idle
   *   queue to the regular queue if it hasn't been executed by then.  If not
   *   passed or a zero value is specified, the event will never be moved to
   *   the regular queue.
   */
  void idleDispatchToMainThread(in nsIRunnable event,
                                [optional] in uint32_t timeout);

  /*
   * A helper method to dispatch a task through nsIDirectTaskDispatcher to the
   * current thread.
   */
  void dispatchDirectTaskToCurrentThread(in nsIRunnable event);

  /**
   * Enter a nested event loop on the current thread, waiting on, and
   * processing events until condition.isDone() returns true.
   *
   * If condition.isDone() throws, this function will throw as well.
   *
   * C++ code should not use this function, instead preferring
   * mozilla::SpinEventLoopUntil.
   */
  void spinEventLoopUntil(in ACString aVeryGoodReasonToDoThis, in nsINestedEventLoopCondition condition);

  /**
   * Similar to the previous method, but the spinning of the event loop
   * terminates when the quit application shutting down starts.
   *
   * C++ code should not use this function, instead preferring
   * mozilla::SpinEventLoopUntil.
   */
  void spinEventLoopUntilOrQuit(in ACString aVeryGoodReasonToDoThis, in nsINestedEventLoopCondition condition);

  /**
   * Spin the current thread's event loop until there are no more pending
   * events.  This could be done with spinEventLoopUntil, but that would
   * require access to the current thread from JavaScript, which we are
   * moving away from.
   */
  void spinEventLoopUntilEmpty();

  /**
   * Return the EventTarget for the main thread.
   */
  readonly attribute nsIEventTarget mainThreadEventTarget;
};