Bug 1676365 - Move SpinEventLoopUntil to separate header. r=#xpcom-reviewers

Differential Revision: https://phabricator.services.mozilla.com/D96556

Depends on D96554
This commit is contained in:
Simon Giesecke 2020-11-23 16:10:41 +00:00
parent be69bdee9a
commit d10d03d076
68 changed files with 175 additions and 95 deletions

View file

@ -4,9 +4,9 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsJSInspector.h"
#include "nsThreadUtils.h"
#include "jsfriendapi.h"
#include "mozilla/HoldDropJSObjects.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/dom/ScriptSettings.h"
#include "nsServiceManagerUtils.h"
#include "nsMemory.h"

View file

@ -92,6 +92,7 @@
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/Preferences.h"
#include "mozilla/Likely.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/Sprintf.h"
#include "mozilla/StorageAccess.h"
#include "mozilla/Unused.h"

View file

@ -88,6 +88,7 @@
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/Preferences.h"
#include "mozilla/Likely.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/Sprintf.h"
#include "mozilla/Unused.h"

View file

@ -8,6 +8,7 @@
#include "mozilla/AutoRestore.h"
#include "mozilla/Mutex.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/StaticMutex.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/Unused.h"

View file

@ -9,6 +9,7 @@
#include "mozilla/Assertions.h"
#include "mozilla/Atomics.h"
#include "mozilla/Attributes.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/Unused.h"
#include "mozilla/dom/BlobImpl.h"
#include "mozilla/dom/File.h"

View file

@ -84,6 +84,7 @@
#include "mozilla/SchedulerGroup.h"
#include "mozilla/Scoped.h"
#include "mozilla/SnappyCompressOutputStream.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/TaskCategory.h"
#include "mozilla/TimeStamp.h"

View file

@ -39,6 +39,7 @@
#include "mozilla/RemoteLazyInputStreamChild.h"
#include "mozilla/SchedulerGroup.h"
#include "mozilla/SharedStyleSheetCache.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/StaticPrefs_dom.h"
#include "mozilla/StaticPrefs_fission.h"
#include "mozilla/StaticPrefs_media.h"

View file

@ -46,6 +46,7 @@
#include "mozilla/ResultExtensions.h"
#include "mozilla/ScopeExit.h"
#include "mozilla/Services.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/StaticPrefs_dom.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/StoragePrincipalHelper.h"

View file

@ -21,6 +21,7 @@
#include "mozilla/Preferences.h"
#include "mozilla/RemoteLazyInputStreamThread.h"
#include "mozilla/ScopeExit.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/StaticMutex.h"
#include "mozilla/StaticPrefs_dom.h"
#include "mozilla/StorageAccess.h"

View file

@ -9,6 +9,7 @@
#include "FlacDemuxer.h"
#include "FuzzingInterface.h"
#include "mozilla/AbstractThread.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "MP3Demuxer.h"
#include "MP4Demuxer.h"
#include "OggDemuxer.h"

View file

@ -24,6 +24,7 @@
#endif
#include "VideoUtils.h"
#include "mozilla/Services.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/StaticPrefs_media.h"
#include "mozilla/SyncRunnable.h"
#include "mozilla/Unused.h"

View file

@ -8,6 +8,7 @@
#include "nsThreadUtils.h"
#include "mozilla/SchedulerGroup.h"
#include "mozilla/SpinEventLoopUntil.h"
class GMPTestMonitor {
public:

View file

@ -15,6 +15,7 @@
#endif // MOZ_WEBRTC
#include "MockCubeb.h"
#include "mozilla/Preferences.h"
#include "mozilla/SpinEventLoopUntil.h"
#define DRIFT_BUFFERING_PREF "media.clockdrift.buffering"

View file

@ -12,6 +12,7 @@
#include "gtest/gtest.h"
#include "mozilla/RefPtr.h"
#include "mozilla/SchedulerGroup.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "nsIFile.h"
#include "nsNSSComponent.h" //For EnsureNSSInitializedChromeOrContent
#include "nsThreadUtils.h"

View file

@ -6,6 +6,7 @@
#include "gtest/gtest.h"
#include "DriftCompensation.h"
#include "mozilla/SpinEventLoopUntil.h"
using namespace mozilla;

View file

@ -12,6 +12,7 @@
#include "WebMDecoder.h"
#include "WebMDemuxer.h"
#include "mozilla/AbstractThread.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "nsMimeTypes.h"
using namespace mozilla;

View file

@ -8,6 +8,7 @@
#include "AnnexB.h"
#include "ImageContainer.h"
#include "mozilla/AbstractThread.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/media/MediaUtils.h" // For media::Await
#include "nsMimeTypes.h"
#include "PEMFactory.h"

View file

@ -48,6 +48,7 @@
#include "mozilla/LoadInfo.h"
#include "mozilla/plugins/PluginBridge.h"
#include "mozilla/plugins/PluginTypes.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/TextUtils.h"
#include "mozilla/Preferences.h"
#include "mozilla/ipc/URIUtils.h"

View file

@ -55,6 +55,7 @@
#include "mozilla/ResultExtensions.h"
#include "mozilla/ScopeExit.h"
#include "mozilla/Services.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/StaticPrefs_dom.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/Telemetry.h"

View file

@ -25,6 +25,7 @@
#include "mozilla/RefPtr.h"
#include "mozilla/Result.h"
#include "mozilla/ResultExtensions.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/Unused.h"
#include "mozilla/Variant.h"

View file

@ -25,6 +25,7 @@
#include "mozilla/dom/LocalStorageCommon.h"
#include "mozilla/Preferences.h"
#include "mozilla/Services.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "nsServiceManagerUtils.h"
namespace mozilla {

View file

@ -36,6 +36,7 @@
#include "mozilla/LoadInfo.h"
#include "mozilla/LoadContext.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/StaticPrefs_dom.h"
#include "mozilla/StaticPrefs_network.h"
#include "mozilla/StaticPrefs_privacy.h"

View file

@ -28,6 +28,7 @@
#include "mozilla/IntegerPrintfMacros.h"
#include "mozilla/Logging.h"
#include "mozilla/SpinEventLoopUntil.h"
using mozilla::LogLevel;

View file

@ -42,6 +42,7 @@
#include "mozilla/dom/ContentChild.h"
#include "mozilla/Unused.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "nsThreadUtils.h"
#if defined(XP_WIN)
# include "WinUtils.h"

View file

@ -9,6 +9,7 @@
#include "MainThreadUtils.h"
#include "VRManagerParent.h"
#include "mozilla/BackgroundHangMonitor.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/layers/CanvasTranslator.h"
#include "mozilla/layers/CompositorManagerParent.h"
#include "mozilla/layers/ImageBridgeParent.h"

View file

@ -20,6 +20,7 @@
#include "mozilla/DebugOnly.h"
#include "mozilla/MozPromise.h"
#include "mozilla/Services.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/Unused.h"
#include "mozilla/dom/ContentChild.h"

View file

@ -47,6 +47,7 @@
#include "mozilla/Encoding.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/Preferences.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/WeakPtr.h"
#include "mozilla/StaticPrefs_dom.h"
#include "mozilla/StaticPrefs_javascript.h"

View file

@ -6,6 +6,7 @@
#include "RemotePrintJobChild.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/Unused.h"
#include "nsPagePrintTimer.h"
#include "nsPrintJob.h"

View file

@ -13,6 +13,7 @@
#include "AudioStreamTrack.h"
#include "mozilla/Mutex.h"
#include "mozilla/RefPtr.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "MediaPipeline.h"
#include "MediaPipelineFilter.h"
#include "MediaTrackGraph.h"

View file

@ -33,6 +33,7 @@
#include "mozilla/ScopeExit.h"
#include "mozilla/Services.h"
#include "mozilla/ServoStyleSet.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/StaticMutex.h"
#include "mozilla/StaticPrefsAll.h"
#include "mozilla/SyncRunnable.h"

View file

@ -24,6 +24,7 @@
#include "prnetdb.h"
#include "nsITimer.h"
#include "mozilla/Atomics.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/net/DNS.h"
#include "mozilla/Utf8.h" // mozilla::Utf8Unit
#include "nsServiceManagerUtils.h"

View file

@ -4,6 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/Logging.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "nsAsyncRedirectVerifyHelper.h"
#include "nsThreadUtils.h"
#include "nsNetUtil.h"

View file

@ -2,6 +2,7 @@
* 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 "mozilla/SpinEventLoopUntil.h"
#include "nsIOService.h"
#include "nsSyncStreamListener.h"
#include "nsThreadUtils.h"

View file

@ -17,6 +17,7 @@
#include "NullHttpTransaction.h"
#include "mozilla/Services.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/Telemetry.h"
#include "mozilla/Unused.h"
#include "mozilla/net/DNS.h"

View file

@ -1,12 +1,12 @@
#ifndef FuzzingStreamListener_h__
#define FuzzingStreamListener_h__
#include "mozilla/SpinEventLoopUntil.h"
#include "nsCOMPtr.h"
#include "nsNetCID.h"
#include "nsString.h"
#include "nsNetUtil.h"
#include "nsIStreamListener.h"
#include "nsThreadUtils.h"
namespace mozilla {
namespace net {

View file

@ -1,4 +1,5 @@
#include "mozilla/Preferences.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "nsCOMPtr.h"
#include "nsNetCID.h"

View file

@ -1,5 +1,6 @@
#include "mozilla/LoadInfo.h"
#include "mozilla/Preferences.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "nsCOMPtr.h"
#include "nsNetCID.h"

View file

@ -2,6 +2,7 @@
#include "FuzzingInterface.h"
#include "FuzzyLayer.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "nsComponentManagerUtils.h"
#include "nsCOMPtr.h"
#include "nsContentUtils.h"

View file

@ -1,5 +1,6 @@
#include "gtest/gtest.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "nsBufferedStreams.h"
#include "nsStreamUtils.h"
#include "nsIThread.h"

View file

@ -8,6 +8,7 @@
#include <stdlib.h>
#include "nsThreadUtils.h"
#include "mozilla/Attributes.h"
#include "mozilla/SpinEventLoopUntil.h"
//-----------------------------------------------------------------------------

View file

@ -1,6 +1,7 @@
#include "gtest/gtest.h"
#include "Helpers.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "nsComponentManagerUtils.h"
#include "nsCOMPtr.h"
#include "nsStreamUtils.h"

View file

@ -5,6 +5,7 @@
#include "nsStreamUtils.h"
#include "nsString.h"
#include "nsStringStream.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/net/PartiallySeekableInputStream.h"
using mozilla::GetCurrentSerialEventTarget;

View file

@ -19,6 +19,7 @@
#include "mozilla/Unused.h"
#include "mozilla/dom/quota/QuotaObject.h"
#include "mozilla/ScopeExit.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/StaticPrefs_storage.h"
#include "mozIStorageCompletionCallback.h"

View file

@ -6,6 +6,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozStorageService.h"
#include "mozStorageConnection.h"

View file

@ -6,6 +6,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/ScopeExit.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/JSONWriter.h"
#include "Database.h"

View file

@ -16,6 +16,7 @@
#include "nsIThread.h"
#include "nsIURI.h"
#include "mozilla/IHistory.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozIStorageConnection.h"
#include "mozIStorageStatement.h"
#include "mozIStorageAsyncStatement.h"

View file

@ -9,6 +9,7 @@
#include "nsIPrefService.h"
#include "nsString.h"
#include "mozilla/Attributes.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/StaticPrefs_layout.h"
#include "nsNetUtil.h"

View file

@ -10,6 +10,7 @@
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/BrowserChild.h"
#include "mozilla/layout/RemotePrintJobChild.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/Unused.h"
#include "nsIDocShell.h"
#include "nsIPrintingPromptService.h"

View file

@ -9,6 +9,7 @@
#include "HashStore.h"
#include "LookupCacheV4.h"
#include "mozilla/Components.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/Unused.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsIThread.h"

View file

@ -20,6 +20,7 @@
#include "mozilla/XREAppData.h"
#include "mozilla/Services.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/Unused.h"
#include "prtime.h"

View file

@ -6,6 +6,7 @@
#include "mozilla/FetchPreloader.h"
#include "mozilla/Maybe.h"
#include "mozilla/PreloadHashKey.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "nsNetUtil.h"
#include "nsIChannel.h"
#include "nsIStreamListener.h"

View file

@ -25,6 +25,7 @@
#include "nsIURL.h"
#include "nsNetUtil.h"
#include "mozilla/Services.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/Unused.h"
#include "nsIOutputStream.h"
#include "nscore.h"

View file

@ -17,6 +17,7 @@
#include "mozilla/PoisonIOInterposer.h"
#include "mozilla/Printf.h"
#include "mozilla/scache/StartupCache.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/StartupTimeline.h"
#include "mozilla/StaticPrefs_toolkit.h"
#include "mozilla/LateWriteChecks.h"

View file

@ -9,6 +9,7 @@
#include "nsXPCOM.h"
#include "nsThreadUtils.h"
#include "gtest/gtest.h"
#include "mozilla/SpinEventLoopUntil.h"
#include <functional>

View file

@ -1,6 +1,7 @@
#include "gtest/gtest.h"
#include "mozilla/InputStreamLengthHelper.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "nsCOMPtr.h"
#include "nsIInputStream.h"
#include "nsStreamUtils.h"

View file

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gtest/gtest.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "nsIAsyncInputStream.h"
#include "nsComponentManagerUtils.h"
#include "nsIInputStream.h"

View file

@ -1,6 +1,7 @@
#include "gtest/gtest.h"
#include "mozilla/NonBlockingAsyncInputStream.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "nsIAsyncInputStream.h"
#include "nsStreamUtils.h"
#include "nsString.h"

View file

@ -1,6 +1,7 @@
#include "gtest/gtest.h"
#include "mozilla/SlicedInputStream.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "nsCOMPtr.h"
#include "nsIInputStream.h"
#include "nsIPipe.h"

View file

@ -8,6 +8,7 @@
#include "nsThreadUtils.h"
#include "mozilla/IdleTaskRunner.h"
#include "mozilla/RefCounted.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/UniquePtr.h"
#include "gtest/gtest.h"

View file

@ -8,6 +8,7 @@
#include "mozilla/Monitor.h"
#include "mozilla/ReentrantMonitor.h"
#include "mozilla/Services.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/StaticPtr.h"
#include "nsDataHashtable.h"
#include "nsXPCOMCIDInternal.h"

View file

@ -0,0 +1,108 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef xpcom_threads_SpinEventLoopUntil_h__
#define xpcom_threads_SpinEventLoopUntil_h__
#include "MainThreadUtils.h"
#include "mozilla/Maybe.h"
#include "nsThreadUtils.h"
#include "xpcpublic.h"
class nsIThread;
// A wrapper for nested event loops.
//
// This function is intended to make code more obvious (do you remember
// what NS_ProcessNextEvent(nullptr, true) means?) and slightly more
// efficient, as people often pass nullptr or NS_GetCurrentThread to
// NS_ProcessNextEvent, which results in needless querying of the current
// thread every time through the loop.
//
// You should use this function in preference to NS_ProcessNextEvent inside
// a loop unless one of the following is true:
//
// * You need to pass `false` to NS_ProcessNextEvent; or
// * You need to do unusual things around the call to NS_ProcessNextEvent,
// such as unlocking mutexes that you are holding.
//
// If you *do* need to call NS_ProcessNextEvent manually, please do call
// NS_GetCurrentThread() outside of your loop and pass the returned pointer
// into NS_ProcessNextEvent for a tiny efficiency win.
namespace mozilla {
// You should normally not need to deal with this template parameter. If
// you enjoy esoteric event loop details, read on.
//
// If you specify that NS_ProcessNextEvent wait for an event, it is possible
// for NS_ProcessNextEvent to return false, i.e. to indicate that an event
// was not processed. This can only happen when the thread has been shut
// down by another thread, but is still attempting to process events outside
// of a nested event loop.
//
// This behavior is admittedly strange. The scenario it deals with is the
// following:
//
// * The current thread has been shut down by some owner thread.
// * The current thread is spinning an event loop waiting for some condition
// to become true.
// * Said condition is actually being fulfilled by another thread, so there
// are timing issues in play.
//
// Thus, there is a small window where the current thread's event loop
// spinning can check the condition, find it false, and call
// NS_ProcessNextEvent to wait for another event. But we don't actually
// want it to wait indefinitely, because there might not be any other events
// in the event loop, and the current thread can't accept dispatched events
// because it's being shut down. Thus, actually blocking would hang the
// thread, which is bad. The solution, then, is to detect such a scenario
// and not actually block inside NS_ProcessNextEvent.
//
// But this is a problem, because we want to return the status of
// NS_ProcessNextEvent to the caller of SpinEventLoopUntil if possible. In
// the above scenario, however, we'd stop spinning prematurely and cause
// all sorts of havoc. We therefore have this template parameter to
// control whether errors are ignored or passed out to the caller of
// SpinEventLoopUntil. The latter is the default; if you find yourself
// wanting to use the former, you should think long and hard before doing
// so, and write a comment like this defending your choice.
enum class ProcessFailureBehavior {
IgnoreAndContinue,
ReportToCaller,
};
template <
ProcessFailureBehavior Behavior = ProcessFailureBehavior::ReportToCaller,
typename Pred>
bool SpinEventLoopUntil(Pred&& aPredicate, nsIThread* aThread = nullptr) {
nsIThread* thread = aThread ? aThread : NS_GetCurrentThread();
// From a latency perspective, spinning the event loop is like leaving script
// and returning to the event loop. Tell the watchdog we stopped running
// script (until we return).
mozilla::Maybe<xpc::AutoScriptActivity> asa;
if (NS_IsMainThread()) {
asa.emplace(false);
}
while (!aPredicate()) {
bool didSomething = NS_ProcessNextEvent(thread, true);
if (Behavior == ProcessFailureBehavior::IgnoreAndContinue) {
// Don't care what happened, continue on.
continue;
} else if (!didSomething) {
return false;
}
}
return true;
}
} // namespace mozilla
#endif // xpcom_threads_SpinEventLoopUntil_h__

View file

@ -8,6 +8,7 @@
#include "mozilla/ThreadEventQueue.h"
#include "LeakRefPtr.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/TimeStamp.h"
#include "nsComponentManagerUtils.h"
#include "nsITimer.h"

View file

@ -64,6 +64,7 @@ EXPORTS.mozilla += [
"RWLock.h",
"SchedulerGroup.h",
"SharedThreadPool.h",
"SpinEventLoopUntil.h",
"StateMirroring.h",
"StateWatching.h",
"SynchronizedEventQueue.h",

View file

@ -31,6 +31,7 @@
#include "mozilla/Preferences.h"
#include "mozilla/SchedulerGroup.h"
#include "mozilla/Services.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/StaticPrefs_threads.h"
#include "mozilla/TaskController.h"
#include "nsXPCOMPrivate.h"

View file

@ -17,6 +17,7 @@
#include "mozilla/InputTaskManager.h"
#include "mozilla/Mutex.h"
#include "mozilla/Preferences.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/TaskQueue.h"
#include "mozilla/ThreadEventQueue.h"

View file

@ -13,6 +13,7 @@
#include "prinrval.h"
#include "mozilla/Logging.h"
#include "mozilla/SchedulerGroup.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "nsThreadSyncDispatch.h"
#include <mutex>

View file

@ -25,15 +25,14 @@
#include "nsIIdleRunnable.h"
#include "nsINamed.h"
#include "nsIRunnable.h"
#include "nsIThread.h"
#include "nsIThreadManager.h"
#include "nsITimer.h"
#include "nsString.h"
#include "prinrval.h"
#include "prthread.h"
#include "xpcpublic.h"
class MessageLoop;
class nsIThread;
//-----------------------------------------------------------------------------
// These methods are alternatives to the methods on nsIThreadManager, provided
@ -283,97 +282,6 @@ extern bool NS_HasPendingEvents(nsIThread* aThread = nullptr);
extern bool NS_ProcessNextEvent(nsIThread* aThread = nullptr,
bool aMayWait = true);
// A wrapper for nested event loops.
//
// This function is intended to make code more obvious (do you remember
// what NS_ProcessNextEvent(nullptr, true) means?) and slightly more
// efficient, as people often pass nullptr or NS_GetCurrentThread to
// NS_ProcessNextEvent, which results in needless querying of the current
// thread every time through the loop.
//
// You should use this function in preference to NS_ProcessNextEvent inside
// a loop unless one of the following is true:
//
// * You need to pass `false` to NS_ProcessNextEvent; or
// * You need to do unusual things around the call to NS_ProcessNextEvent,
// such as unlocking mutexes that you are holding.
//
// If you *do* need to call NS_ProcessNextEvent manually, please do call
// NS_GetCurrentThread() outside of your loop and pass the returned pointer
// into NS_ProcessNextEvent for a tiny efficiency win.
namespace mozilla {
// You should normally not need to deal with this template parameter. If
// you enjoy esoteric event loop details, read on.
//
// If you specify that NS_ProcessNextEvent wait for an event, it is possible
// for NS_ProcessNextEvent to return false, i.e. to indicate that an event
// was not processed. This can only happen when the thread has been shut
// down by another thread, but is still attempting to process events outside
// of a nested event loop.
//
// This behavior is admittedly strange. The scenario it deals with is the
// following:
//
// * The current thread has been shut down by some owner thread.
// * The current thread is spinning an event loop waiting for some condition
// to become true.
// * Said condition is actually being fulfilled by another thread, so there
// are timing issues in play.
//
// Thus, there is a small window where the current thread's event loop
// spinning can check the condition, find it false, and call
// NS_ProcessNextEvent to wait for another event. But we don't actually
// want it to wait indefinitely, because there might not be any other events
// in the event loop, and the current thread can't accept dispatched events
// because it's being shut down. Thus, actually blocking would hang the
// thread, which is bad. The solution, then, is to detect such a scenario
// and not actually block inside NS_ProcessNextEvent.
//
// But this is a problem, because we want to return the status of
// NS_ProcessNextEvent to the caller of SpinEventLoopUntil if possible. In
// the above scenario, however, we'd stop spinning prematurely and cause
// all sorts of havoc. We therefore have this template parameter to
// control whether errors are ignored or passed out to the caller of
// SpinEventLoopUntil. The latter is the default; if you find yourself
// wanting to use the former, you should think long and hard before doing
// so, and write a comment like this defending your choice.
enum class ProcessFailureBehavior {
IgnoreAndContinue,
ReportToCaller,
};
template <
ProcessFailureBehavior Behavior = ProcessFailureBehavior::ReportToCaller,
typename Pred>
bool SpinEventLoopUntil(Pred&& aPredicate, nsIThread* aThread = nullptr) {
nsIThread* thread = aThread ? aThread : NS_GetCurrentThread();
// From a latency perspective, spinning the event loop is like leaving script
// and returning to the event loop. Tell the watchdog we stopped running
// script (until we return).
mozilla::Maybe<xpc::AutoScriptActivity> asa;
if (NS_IsMainThread()) {
asa.emplace(false);
}
while (!aPredicate()) {
bool didSomething = NS_ProcessNextEvent(thread, true);
if (Behavior == ProcessFailureBehavior::IgnoreAndContinue) {
// Don't care what happened, continue on.
continue;
} else if (!didSomething) {
return false;
}
}
return true;
}
} // namespace mozilla
/**
* Returns true if we're in the compositor thread.
*

View file

@ -56,6 +56,7 @@
#include "mozilla/Preferences.h"
#include "mozilla/PresShell.h"
#include "mozilla/Services.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/dom/BarProps.h"
#include "mozilla/dom/DOMRect.h"
#include "mozilla/dom/Element.h"