replaced by .editorconfig # ignore-this-changeset Differential Revision: https://phabricator.services.mozilla.com/D287878
295 lines
12 KiB
Plaintext
295 lines
12 KiB
Plaintext
/* 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"
|
|
#include "nsIRunnable.idl"
|
|
%{C++
|
|
#include "nsCOMPtr.h"
|
|
#include "mozilla/AlreadyAddRefed.h"
|
|
#include "mozilla/Atomics.h"
|
|
#include "mozilla/TypedEnumBits.h"
|
|
|
|
class nsITargetShutdownTask;
|
|
%}
|
|
|
|
native alreadyAddRefed_nsIRunnable(already_AddRefed<nsIRunnable>);
|
|
[ptr] native nsITargetShutdownTask(nsITargetShutdownTask);
|
|
|
|
[builtinclass, scriptable, rust_sync, uuid(a03b8b63-af8b-4164-b0e5-c41e8b2b7cfa)]
|
|
interface nsIEventTarget : nsISupports
|
|
{
|
|
/**
|
|
* Flags used to customize the behaviour of a `Dispatch` call.
|
|
*
|
|
* WARNING: These flags are generally hints, and are not universally supported
|
|
* by all nsIEventTarget implementations. An implementation may ignore some or
|
|
* all of these flags.
|
|
*
|
|
* HISTORIC NOTE: There used to be a `DISPATCH_SYNC` flag which would spin a
|
|
* nested event loop while dispatching (and could not be safely ignored by
|
|
* event target implementations), but this has since been removed.
|
|
*/
|
|
cenum DispatchFlags : 32 {
|
|
/**
|
|
* DISPATCH_NORMAL corresponds to the absense of other flags. This is used
|
|
* for dispatching async events to an event target which will be queued for
|
|
* later processing.
|
|
*/
|
|
DISPATCH_NORMAL = 0,
|
|
|
|
// NOTE: 1 << 0 used to be DISPATCH_SYNC
|
|
|
|
/**
|
|
* This flag specifies that the dispatch is occurring from a running event
|
|
* that was dispatched to the same event target, and that event is about to
|
|
* finish.
|
|
*
|
|
* A thread pool can use this as an optimization hint to not spin up
|
|
* another thread, since the current thread is about to become idle.
|
|
*/
|
|
DISPATCH_AT_END = 1 << 1,
|
|
|
|
/**
|
|
* This flag specifies that the dispatched event may block the thread on
|
|
* which it executes, usually by doing some sort of I/O. This information
|
|
* may be used by the event target to execute the job on a thread
|
|
* specifically dedicated to doing I/O, leaving other threads available for
|
|
* CPU-intensive work.
|
|
*/
|
|
DISPATCH_EVENT_MAY_BLOCK = 1 << 2,
|
|
|
|
/**
|
|
* This flag specifies that the dispatched event should be delivered to the
|
|
* target thread even if the thread has been configured to block dispatching
|
|
* of runnables. This is generally done for threads which have their own
|
|
* internal event loop, such as thread pools or the timer thread, and will not
|
|
* service runnables dispatched to them until shutdown.
|
|
*/
|
|
DISPATCH_IGNORE_BLOCK_DISPATCH = 1 << 3,
|
|
|
|
/**
|
|
* This flag specifies that the caller of the given dispatch is prepared to
|
|
* handle dispatch failures itself.
|
|
*
|
|
* Some nsIEventTarget implementations, such as nsThread, leak the passed-in
|
|
* runnable if there is a failure when dispatching (e.g. due to the thread
|
|
* being destroyed). This is done as many callers are unprepared to handle
|
|
* calls to Dispatch failing, and could otherwise e.g. destroy a object on
|
|
* the wrong thread.
|
|
*
|
|
* By specifying DISPATCH_FALLIBLE, you communicate to the nsIEventTarget
|
|
* implementation that you are prepared to handle the consequences of the
|
|
* dispatch failing. nsIEventTarget implementations should neither leak
|
|
* passed-in runnables nor fire assertions on state-related error codepaths
|
|
* (such as late shutdown dispatch assertions) when DISPATCH_FALLIBLE is
|
|
* specified.
|
|
*
|
|
* When using DISPATCH_FALLIBLE, the caller must be careful that the event
|
|
* object is safe to discard on the calling thread, and that other systems
|
|
* do not depend on the runnable completing on error cases.
|
|
*
|
|
* NOTE: Many nsIEventTarget implementations (including TaskQueue and
|
|
* nsThreadPool) never leak the passed-in runnable on failure, whether or
|
|
* not this flag is specified. Dispatched events may always be released by
|
|
* the dispatcher on error for those types.
|
|
*
|
|
* See bug 803174, bug 1237213 and bug 1824189 for historical context.
|
|
*/
|
|
DISPATCH_FALLIBLE = 1 << 4,
|
|
};
|
|
|
|
/**
|
|
* IsOnCurrentThread() should return true if events dispatched to this target
|
|
* can possibly run on the current thread, and false otherwise. In the case
|
|
* of an nsIEventTarget for a thread pool, it should return true on all
|
|
* threads in the pool. In the case of a non-thread nsIEventTarget such as
|
|
* ThrottledEventQueue, it should return true on the thread where events are
|
|
* expected to be processed, even if no events from the queue are actually
|
|
* being processed right now.
|
|
*
|
|
* When called on an nsISerialEventTarget, IsOnCurrentThread can be used to
|
|
* ensure that no other thread has "ownership" of the event target. As such,
|
|
* it's useful for asserting that an object is only used on a particular
|
|
* thread. IsOnCurrentThread can't guarantee that the current event has been
|
|
* dispatched through a particular event target.
|
|
*
|
|
* The infallible version of IsOnCurrentThread() is optimized to avoid a
|
|
* virtual call for non-thread event targets. Thread targets should set
|
|
* mThread to their virtual PRThread. Non-thread targets should leave
|
|
* mThread null and implement IsOnCurrentThreadInfallible() to
|
|
* return the correct answer.
|
|
*
|
|
* The fallible version of IsOnCurrentThread may return errors, such as during
|
|
* shutdown. If it does not return an error, it should return the same result
|
|
* as the infallible version. The infallible method should return the correct
|
|
* result regardless of whether the fallible method returns an error.
|
|
*/
|
|
%{C++
|
|
public:
|
|
// Infallible. Defined in nsThreadUtils.cpp. Delegates to
|
|
// IsOnCurrentThreadInfallible when mThread is null.
|
|
bool IsOnCurrentThread();
|
|
|
|
protected:
|
|
mozilla::Atomic<PRThread*> mThread;
|
|
|
|
nsIEventTarget() : mThread(nullptr) {}
|
|
%}
|
|
// Note that this method is protected. We define it through IDL, rather than
|
|
// in a %{C++ block, to ensure that the correct method indices are recorded
|
|
// for XPConnect purposes.
|
|
[noscript,notxpcom] boolean isOnCurrentThreadInfallible();
|
|
%{C++
|
|
public:
|
|
%}
|
|
|
|
// Fallible version of IsOnCurrentThread.
|
|
boolean isOnCurrentThread();
|
|
|
|
/* until we can get rid of all uses, keep the non-alreadyAddRefed<> version */
|
|
%{C++
|
|
nsresult Dispatch(nsIRunnable* aEvent, DispatchFlags aFlags) {
|
|
return Dispatch(nsCOMPtr<nsIRunnable>(aEvent).forget(), aFlags);
|
|
}
|
|
%}
|
|
|
|
/**
|
|
* Dispatch an event to this event target. This function may be called from
|
|
* any thread, and it may be called re-entrantly.
|
|
*
|
|
* @param event
|
|
* The alreadyAddRefed<> event to dispatch.
|
|
* NOTE that the event should be leaked if it fails to dispatch unless
|
|
* NS_DISPATCH_FALLIBLE is passed.
|
|
* @param flags
|
|
* The flags modifying event dispatch. The flags are described in detail
|
|
* above.
|
|
*
|
|
* @throws NS_ERROR_INVALID_ARG
|
|
* Indicates that event is null.
|
|
* @throws NS_ERROR_UNEXPECTED
|
|
* Indicates that the thread is shutting down and has finished processing
|
|
* events, so this event would never run and has not been dispatched.
|
|
*/
|
|
[noscript, binaryname(Dispatch)] void dispatchFromC(in alreadyAddRefed_nsIRunnable event,
|
|
[default(DISPATCH_NORMAL)] in nsIEventTarget_DispatchFlags flags);
|
|
|
|
/**
|
|
* Version of Dispatch to expose to JS, which doesn't require an alreadyAddRefed<>
|
|
* (it will be converted to that internally)
|
|
*
|
|
* @param event
|
|
* The (raw) event to dispatch.
|
|
* @param flags
|
|
* The flags modifying event dispatch. The flags are described in detail
|
|
* above.
|
|
*
|
|
* @throws NS_ERROR_INVALID_ARG
|
|
* Indicates that event is null.
|
|
* @throws NS_ERROR_UNEXPECTED
|
|
* Indicates that the thread is shutting down and has finished processing
|
|
* events, so this event would never run and has not been dispatched.
|
|
*/
|
|
[binaryname(DispatchFromScript)] void dispatch(in nsIRunnable event, in nsIEventTarget_DispatchFlags flags);
|
|
|
|
/**
|
|
* Dispatch an event to this event target, but do not run it before delay
|
|
* milliseconds have passed. This function may be called from any thread.
|
|
*
|
|
* @param event
|
|
* The alreadyAddrefed<> event to dispatch.
|
|
* @param delay
|
|
* The delay (in ms) before running the event. If event does not rise to
|
|
* the top of the event queue before the delay has passed, it will be set
|
|
* aside to execute once the delay has passed. Otherwise, it will be
|
|
* executed immediately.
|
|
*
|
|
* @throws NS_ERROR_INVALID_ARG
|
|
* Indicates that event is null.
|
|
* @throws NS_ERROR_UNEXPECTED
|
|
* Indicates that the thread is shutting down and has finished processing
|
|
* events, so this event would never run and has not been dispatched, or
|
|
* that delay is zero.
|
|
*/
|
|
[noscript] void delayedDispatch(in alreadyAddRefed_nsIRunnable event, in unsigned long delay);
|
|
|
|
/**
|
|
* Register an task to be run on this event target when it begins shutting
|
|
* down. Shutdown tasks may be run in any order, and this function may be
|
|
* called from any thread.
|
|
*
|
|
* The event target may or may not continue accepting events during or after
|
|
* the shutdown task. The precise behaviour here depends on the event target.
|
|
*
|
|
* @param task
|
|
* The task to be registered to the target thread.
|
|
* NOTE that unlike `dispatch`, this will not leak the task if it fails.
|
|
*
|
|
* @throws NS_ERROR_INVALID_ARG
|
|
* Indicates that task is null.
|
|
* @throws NS_ERROR_NOT_IMPLEMENTED
|
|
* Indicates that this event target doesn't support shutdown tasks.
|
|
* @throws NS_ERROR_UNEXPECTED
|
|
* Indicates that the thread is already shutting down, and no longer
|
|
* accepting events.
|
|
*/
|
|
[noscript] void registerShutdownTask(in nsITargetShutdownTask task);
|
|
|
|
/**
|
|
* Unregisters an task previously registered with registerShutdownTask. This
|
|
* function may be called from any thread.
|
|
*
|
|
* @param task
|
|
* The task previously registered with registerShutdownTask
|
|
*
|
|
* @throws NS_ERROR_INVALID_ARG
|
|
* Indicates that task is null.
|
|
* @throws NS_ERROR_NOT_IMPLEMENTED
|
|
* Indicates that this event target doesn't support shutdown tasks.
|
|
* @throws NS_ERROR_UNEXPECTED
|
|
* Indicates that the thread is already shutting down, and no longer
|
|
* accepting events, or that the shutdown task cannot be found.
|
|
*/
|
|
[noscript] void unregisterShutdownTask(in nsITargetShutdownTask task);
|
|
|
|
cenum FeatureFlags : 32 {
|
|
SUPPORTS_BASE = 0,
|
|
// Indicates that the event target supports shutdown tasks.
|
|
SUPPORTS_SHUTDOWN_TASKS = 1 << 0,
|
|
// Indicates whether or not it is possible to dispatch events to this
|
|
// event target while its shutdown tasks are executed from those.
|
|
SUPPORTS_SHUTDOWN_TASK_DISPATCH = 1 << 1,
|
|
// Indicates whether the event target supports prioritization.
|
|
// Events implementing nsIRunnablePriority can get run in a different
|
|
// order than they were dispatched.
|
|
SUPPORTS_PRIORITIZATION = 1 << 2,
|
|
};
|
|
|
|
/**
|
|
* Returns a FeatureFlags bitmask indicating supported features.
|
|
*/
|
|
[noscript, notxpcom] nsIEventTarget_FeatureFlags getFeatures();
|
|
|
|
};
|
|
|
|
%{C++
|
|
// convenient aliases:
|
|
#define NS_DISPATCH_NORMAL nsIEventTarget::DISPATCH_NORMAL
|
|
#define NS_DISPATCH_AT_END nsIEventTarget::DISPATCH_AT_END
|
|
#define NS_DISPATCH_EVENT_MAY_BLOCK nsIEventTarget::DISPATCH_EVENT_MAY_BLOCK
|
|
#define NS_DISPATCH_IGNORE_BLOCK_DISPATCH nsIEventTarget::DISPATCH_IGNORE_BLOCK_DISPATCH
|
|
#define NS_DISPATCH_FALLIBLE nsIEventTarget::DISPATCH_FALLIBLE
|
|
|
|
// Convenience bitwise operators for the flag cenum
|
|
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsIEventTarget::DispatchFlags)
|
|
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsIEventTarget::FeatureFlags)
|
|
|
|
// Convenient NS_DECL variant that includes some C++-only methods.
|
|
#define NS_DECL_NSIEVENTTARGET_FULL \
|
|
NS_DECL_NSIEVENTTARGET \
|
|
/* Avoid hiding these methods */ \
|
|
using nsIEventTarget::Dispatch; \
|
|
using nsIEventTarget::IsOnCurrentThread;
|
|
%}
|