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#include "nsIRunnable.idl" 9%{C++ 10#include "nsCOMPtr.h" 11#include "mozilla/AlreadyAddRefed.h" 12#include "mozilla/Atomics.h" 13%} 14 15native alreadyAddRefed_nsIRunnable(already_AddRefed<nsIRunnable>); 16 17[builtinclass, scriptable, uuid(a03b8b63-af8b-4164-b0e5-c41e8b2b7cfa)] 18interface nsIEventTarget : nsISupports 19{ 20 /* until we can get rid of all uses, keep the non-alreadyAddRefed<> version */ 21%{C++ 22 nsresult Dispatch(nsIRunnable* aEvent, uint32_t aFlags) { 23 return Dispatch(nsCOMPtr<nsIRunnable>(aEvent).forget(), aFlags); 24 } 25%} 26 27 /** 28 * This flag specifies the default mode of event dispatch, whereby the event 29 * is simply queued for later processing. When this flag is specified, 30 * dispatch returns immediately after the event is queued. 31 */ 32 const unsigned long DISPATCH_NORMAL = 0; 33 34 /** 35 * This flag specifies the synchronous mode of event dispatch, in which the 36 * dispatch method does not return until the event has been processed. 37 * 38 * NOTE: passing this flag to dispatch may have the side-effect of causing 39 * other events on the current thread to be processed while waiting for the 40 * given event to be processed. 41 */ 42 const unsigned long DISPATCH_SYNC = 1; 43 44 /** 45 * This flag specifies that the dispatch is occurring from a running event 46 * that was dispatched to the same event target, and that event is about to 47 * finish. 48 * 49 * A thread pool can use this as an optimization hint to not spin up 50 * another thread, since the current thread is about to become idle. 51 * 52 * These events are always async. 53 */ 54 const unsigned long DISPATCH_AT_END = 2; 55 56 /** 57 * This flag specifies that the dispatched event may block the thread on 58 * which it executes, usually by doing some sort of I/O. This information 59 * may be used by the event target to execute the job on a thread 60 * specifically dedicated to doing I/O, leaving other threads available for 61 * CPU-intensive work. 62 */ 63 const unsigned long DISPATCH_EVENT_MAY_BLOCK = 4; 64 65 /** 66 * IsOnCurrentThread() should return true if events dispatched to this target 67 * can possibly run on the current thread, and false otherwise. In the case 68 * of an nsIEventTarget for a thread pool, it should return true on all 69 * threads in the pool. In the case of a non-thread nsIEventTarget such as 70 * ThrottledEventQueue, it should return true on the thread where events are 71 * expected to be processed, even if no events from the queue are actually 72 * being processed right now. 73 * 74 * When called on an nsISerialEventTarget, IsOnCurrentThread can be used to 75 * ensure that no other thread has "ownership" of the event target. As such, 76 * it's useful for asserting that an object is only used on a particular 77 * thread. IsOnCurrentThread can't guarantee that the current event has been 78 * dispatched through a particular event target. 79 * 80 * The infallible version of IsOnCurrentThread() is optimized to avoid a 81 * virtual call for non-thread event targets. Thread targets should set 82 * mThread to their virtual PRThread. Non-thread targets should leave 83 * mThread null and implement IsOnCurrentThreadInfallible() to 84 * return the correct answer. 85 * 86 * The fallible version of IsOnCurrentThread may return errors, such as during 87 * shutdown. If it does not return an error, it should return the same result 88 * as the infallible version. The infallible method should return the correct 89 * result regardless of whether the fallible method returns an error. 90 */ 91 %{C++ 92public: 93 // Infallible. Defined in nsThreadUtils.cpp. Delegates to 94 // IsOnCurrentThreadInfallible when mThread is null. 95 bool IsOnCurrentThread(); 96 97protected: 98 mozilla::Atomic<PRThread*> mThread; 99 100 nsIEventTarget() : mThread(nullptr) {} 101 %} 102 // Note that this method is protected. We define it through IDL, rather than 103 // in a %{C++ block, to ensure that the correct method indices are recorded 104 // for XPConnect purposes. 105 [noscript,notxpcom] boolean isOnCurrentThreadInfallible(); 106 %{C++ 107public: 108 %} 109 110 // Fallible version of IsOnCurrentThread. 111 boolean isOnCurrentThread(); 112 113 /** 114 * Dispatch an event to this event target. This function may be called from 115 * any thread, and it may be called re-entrantly. 116 * 117 * @param event 118 * The alreadyAddRefed<> event to dispatch. 119 * NOTE that the event will be leaked if it fails to dispatch. 120 * @param flags 121 * The flags modifying event dispatch. The flags are described in detail 122 * below. 123 * 124 * @throws NS_ERROR_INVALID_ARG 125 * Indicates that event is null. 126 * @throws NS_ERROR_UNEXPECTED 127 * Indicates that the thread is shutting down and has finished processing 128 * events, so this event would never run and has not been dispatched. 129 */ 130 [noscript, binaryname(Dispatch)] void dispatchFromC(in alreadyAddRefed_nsIRunnable event, 131 [default(DISPATCH_NORMAL)] in unsigned long flags); 132 /** 133 * Version of Dispatch to expose to JS, which doesn't require an alreadyAddRefed<> 134 * (it will be converted to that internally) 135 * 136 * @param event 137 * The (raw) event to dispatch. 138 * @param flags 139 * The flags modifying event dispatch. The flags are described in detail 140 * below. 141 * 142 * @throws NS_ERROR_INVALID_ARG 143 * Indicates that event is null. 144 * @throws NS_ERROR_UNEXPECTED 145 * Indicates that the thread is shutting down and has finished processing 146 * events, so this event would never run and has not been dispatched. 147 */ 148 [binaryname(DispatchFromScript)] void dispatch(in nsIRunnable event, in unsigned long flags); 149 /** 150 * Dispatch an event to this event target, but do not run it before delay 151 * milliseconds have passed. This function may be called from any thread. 152 * 153 * @param event 154 * The alreadyAddrefed<> event to dispatch. 155 * @param delay 156 * The delay (in ms) before running the event. If event does not rise to 157 * the top of the event queue before the delay has passed, it will be set 158 * aside to execute once the delay has passed. Otherwise, it will be 159 * executed immediately. 160 * 161 * @throws NS_ERROR_INVALID_ARG 162 * Indicates that event is null. 163 * @throws NS_ERROR_UNEXPECTED 164 * Indicates that the thread is shutting down and has finished processing 165 * events, so this event would never run and has not been dispatched, or 166 * that delay is zero. 167 */ 168 [noscript] void delayedDispatch(in alreadyAddRefed_nsIRunnable event, in unsigned long delay); 169}; 170 171%{C++ 172// convenient aliases: 173#define NS_DISPATCH_NORMAL nsIEventTarget::DISPATCH_NORMAL 174#define NS_DISPATCH_SYNC nsIEventTarget::DISPATCH_SYNC 175#define NS_DISPATCH_AT_END nsIEventTarget::DISPATCH_AT_END 176#define NS_DISPATCH_EVENT_MAY_BLOCK nsIEventTarget::DISPATCH_EVENT_MAY_BLOCK 177 178// Convenient NS_DECL variant that includes some C++-only methods. 179#define NS_DECL_NSIEVENTTARGET_FULL \ 180 NS_DECL_NSIEVENTTARGET \ 181 /* Avoid hiding these methods */ \ 182 using nsIEventTarget::Dispatch; \ 183 using nsIEventTarget::IsOnCurrentThread; 184%} 185