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/* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7#include "nsISupports.idl" 8 9[ptr] native PRThread(PRThread); 10 11interface nsIEventTarget; 12interface nsIRunnable; 13interface nsIThread; 14 15[scriptable, function, uuid(039a227d-0cb7-44a5-a8f9-dbb7071979f2)] 16interface nsINestedEventLoopCondition : nsISupports 17{ 18 /** 19 * Returns true if the current nested event loop should stop spinning. 20 */ 21 bool isDone(); 22}; 23 24/** 25 * An interface for creating and locating nsIThread instances. 26 */ 27[scriptable, uuid(1be89eca-e2f7-453b-8d38-c11ba247f6f3)] 28interface nsIThreadManager : nsISupports 29{ 30 /** 31 * Default number of bytes reserved for a thread's stack, if no stack size 32 * is specified in newThread(). 33 * 34 * Defaults can be a little overzealous for many platforms. 35 * 36 * On Linux and OS X, for instance, the default thread stack size is whatever 37 * getrlimit(RLIMIT_STACK) returns, which is often set at 8MB. Or, on Linux, 38 * if the stack size is unlimited, we fall back to 2MB. This causes particular 39 * problems on Linux, which allocates 2MB huge VM pages, and will often 40 * immediately allocate them for any stacks which are 2MB or larger. 41 * 42 * The default on Windows is 1MB, which is a little more reasonable. But the 43 * vast majority of our threads don't need anywhere near that much space. 44 * 45 * ASan, TSan and non-opt builds, however, often need a bit more, so give 46 * them the platform default. 47 */ 48%{C++ 49#if defined(MOZ_ASAN) || defined(MOZ_TSAN) || !defined(__OPTIMIZE__) 50 static constexpr uint32_t DEFAULT_STACK_SIZE = 0; 51#else 52 static constexpr uint32_t DEFAULT_STACK_SIZE = 256 * 1024; 53#endif 54 55 static const uint32_t kThreadPoolStackSize = DEFAULT_STACK_SIZE; 56%} 57 58 /** 59 * Create a new thread (a global, user PRThread). 60 * 61 * @param creationFlags 62 * Reserved for future use. Pass 0. 63 * @param stackSize 64 * Number of bytes to reserve for the thread's stack. 0 means use platform 65 * default. 66 * 67 * @returns 68 * The newly created nsIThread object. 69 */ 70 nsIThread newThread(in unsigned long creationFlags, [optional] in unsigned long stackSize); 71 72 /** 73 * Create a new thread (a global, user PRThread) with the specified name. 74 * 75 * @param name 76 * The name of the thread. Passing an empty name is equivalent to 77 * calling newThread(0, stackSize), i.e. the thread will not be named. 78 * @param stackSize 79 * Number of bytes to reserve for the thread's stack. 0 means use platform 80 * default. 81 * 82 * @returns 83 * The newly created nsIThread object. 84 */ 85 [noscript] nsIThread newNamedThread(in ACString name, [optional] in unsigned long stackSize); 86 87 /** 88 * Get the main thread. 89 */ 90 readonly attribute nsIThread mainThread; 91 92 /** 93 * Get the current thread. If the calling thread does not already have a 94 * nsIThread associated with it, then a new nsIThread will be created and 95 * associated with the current PRThread. 96 */ 97 readonly attribute nsIThread currentThread; 98 99 /** 100 * This queues a runnable to the main thread. It's a shortcut for JS callers 101 * to be used instead of 102 * .mainThread.dispatch(runnable, Ci.nsIEventTarget.DISPATCH_NORMAL); 103 * or 104 * .currentThread.dispatch(runnable, Ci.nsIEventTarget.DISPATCH_NORMAL); 105 * C++ callers should instead use NS_DispatchToMainThread. 106 */ 107 [optional_argc] 108 void dispatchToMainThread(in nsIRunnable event, [optional] in uint32_t priority); 109 110 /** 111 * This queues a runnable to the main thread's idle queue. 112 * 113 * @param event 114 * The event to dispatch. 115 * @param timeout 116 * The time in milliseconds until this event should be moved from the idle 117 * queue to the regular queue if it hasn't been executed by then. If not 118 * passed or a zero value is specified, the event will never be moved to 119 * the regular queue. 120 */ 121 void idleDispatchToMainThread(in nsIRunnable event, 122 [optional] in uint32_t timeout); 123 124 /** 125 * Enter a nested event loop on the current thread, waiting on, and 126 * processing events until condition.isDone() returns true. 127 * 128 * If condition.isDone() throws, this function will throw as well. 129 * 130 * C++ code should not use this function, instead preferring 131 * mozilla::SpinEventLoopUntil. 132 */ 133 void spinEventLoopUntil(in nsINestedEventLoopCondition condition); 134 135 /** 136 * Similar to the previous method, but the spinning of the event loop 137 * terminates when the shutting down starts. 138 * 139 * C++ code should not use this function, instead preferring 140 * mozilla::SpinEventLoopUntil. 141 */ 142 void spinEventLoopUntilOrShutdown(in nsINestedEventLoopCondition condition); 143 144 /** 145 * Spin the current thread's event loop until there are no more pending 146 * events. This could be done with spinEventLoopUntil, but that would 147 * require access to the current thread from JavaScript, which we are 148 * moving away from. 149 */ 150 void spinEventLoopUntilEmpty(); 151 152 /** 153 * Return the EventTarget for the main thread. 154 */ 155 readonly attribute nsIEventTarget mainThreadEventTarget; 156}; 157