Bug 1650277 - P3. Use a media taskqueue with the MediaManager. r=jib

Rename PostTask methods into Dispatch to be more in-line with the current naming convention as PostTask pretty much always referred to the MessageLoop's method.

Differential Revision: https://phabricator.services.mozilla.com/D82159
This commit is contained in:
Jean-Yves Avenard 2020-07-09 06:12:10 +00:00
parent 7920483bbe
commit 090a977b95
6 changed files with 65 additions and 79 deletions

View File

@ -9,27 +9,15 @@
#include "AudioCaptureTrack.h"
#include "AudioDeviceInfo.h"
#include "AudioStreamTrack.h"
#include "CubebDeviceEnumerator.h"
#include "MediaTimer.h"
#include "MediaTrackConstraints.h"
#include "MediaTrackGraphImpl.h"
#include "MediaTrackListener.h"
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
#include "VideoStreamTrack.h"
#include "VideoUtils.h"
#include "mozilla/Base64.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/FeaturePolicyUtils.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/MediaDeviceInfo.h"
#include "mozilla/dom/MediaDevices.h"
#include "mozilla/dom/MediaStreamBinding.h"
#include "mozilla/dom/MediaStreamTrackBinding.h"
#include "mozilla/dom/GetUserMediaRequestBinding.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/UserActivation.h"
#include "mozilla/dom/WindowContext.h"
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/media/MediaChild.h"
#include "mozilla/media/MediaTaskUtils.h"
#include "mozilla/MozPromise.h"
#include "mozilla/NullPrincipal.h"
#include "mozilla/PeerIdentity.h"
@ -38,6 +26,22 @@
#include "mozilla/StaticPrefs_media.h"
#include "mozilla/Telemetry.h"
#include "mozilla/Types.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/FeaturePolicyUtils.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/GetUserMediaRequestBinding.h"
#include "mozilla/dom/MediaDeviceInfo.h"
#include "mozilla/dom/MediaDevices.h"
#include "mozilla/dom/MediaStreamBinding.h"
#include "mozilla/dom/MediaStreamTrackBinding.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/UserActivation.h"
#include "mozilla/dom/WindowContext.h"
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/media/MediaChild.h"
#include "mozilla/media/MediaTaskUtils.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsArray.h"
#include "nsContentUtils.h"
@ -53,15 +57,11 @@
#include "nsNetCID.h"
#include "nsNetUtil.h"
#include "nsPIDOMWindow.h"
#include "nspr.h"
#include "nsProxyRelease.h"
#include "nss.h"
#include "nsVariant.h"
#include "nspr.h"
#include "nss.h"
#include "pk11pub.h"
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
#include "VideoStreamTrack.h"
#include "VideoUtils.h"
#include "CubebDeviceEnumerator.h"
/* Using WebRTC backend on Desktops (Mac, Windows, Linux), otherwise default */
#include "MediaEngineDefault.h"
@ -72,11 +72,12 @@
#endif
#if defined(XP_WIN)
# include "mozilla/WindowsVersion.h"
# include <objbase.h>
# include <winsock2.h>
# include <iphlpapi.h>
# include <objbase.h>
# include <tchar.h>
# include <winsock2.h>
# include "mozilla/WindowsVersion.h"
#endif
// XXX Workaround for bug 986974 to maintain the existing broken semantics
@ -1412,9 +1413,9 @@ RefPtr<MediaManager::BadConstraintsPromise> MediaManager::SelectSettings(
// Algorithm accesses device capabilities code and must run on media thread.
// Modifies passed-in aSources.
return MediaManager::PostTask<BadConstraintsPromise>(
__func__, [aConstraints, aSources, aIsChrome](
MozPromiseHolder<BadConstraintsPromise>& holder) mutable {
return MediaManager::Dispatch<BadConstraintsPromise>(
__func__, [aConstraints, aSources,
aIsChrome](MozPromiseHolder<BadConstraintsPromise>& holder) {
auto& sources = *aSources;
// Since the advanced part of the constraints algorithm needs to know
@ -1894,14 +1895,14 @@ RefPtr<MediaManager::MgrPromise> MediaManager::EnumerateRawDevices(
} else {
// Don't need to ask permission to retrieve list of all devices;
// post the retrieval task immediately.
MediaManager::PostTask(task.forget());
MediaManager::Dispatch(task.forget());
}
return promise;
}
MediaManager::MediaManager(UniquePtr<base::Thread> aMediaThread)
: mMediaThread(std::move(aMediaThread)), mBackend(nullptr) {
MediaManager::MediaManager(already_AddRefed<TaskQueue> aMediaThread)
: mMediaThread(aMediaThread), mBackend(nullptr) {
mPrefs.mFreq = 1000; // 1KHz test tone
mPrefs.mWidth = 0; // adaptive default
mPrefs.mHeight = 0; // adaptive default
@ -1963,9 +1964,7 @@ StaticMutex MediaManager::sSingletonMutex;
/* static */
bool MediaManager::IsInMediaThread() {
StaticMutexAutoLock lock(sSingletonMutex);
return sSingleton ? (sSingleton->mMediaThread->thread_id() ==
PlatformThread::CurrentId())
: false;
return sSingleton && sSingleton->mMediaThread->IsOnCurrentThread();
}
#endif
@ -1984,20 +1983,11 @@ MediaManager* MediaManager::Get() {
timesCreated++;
MOZ_RELEASE_ASSERT(timesCreated == 1);
{
UniquePtr<base::Thread> mediaThread =
MakeUnique<base::Thread>("MediaManager");
RefPtr<TaskQueue> mediaThread = new TaskQueue(
GetMediaThreadPool(MediaThreadType::PLAYBACK), "MediaManager");
LOG("New Media thread for gum");
base::Thread::Options options;
options.message_loop_type = MessageLoop::TYPE_MOZILLA_NONMAINTHREAD;
if (!mediaThread->StartWithOptions(options)) {
MOZ_CRASH();
}
LOG("New Media thread for gum");
sSingleton = new MediaManager(std::move(mediaThread));
}
sSingleton = new MediaManager(mediaThread.forget());
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (obs) {
@ -2103,7 +2093,7 @@ void MediaManager::StartupInit() {
}
/* static */
void MediaManager::PostTask(already_AddRefed<Runnable> task) {
void MediaManager::Dispatch(already_AddRefed<Runnable> task) {
if (sHasShutdown) {
// Can't safely delete task here since it may have items with specific
// thread-release requirements.
@ -2114,16 +2104,16 @@ void MediaManager::PostTask(already_AddRefed<Runnable> task) {
}
NS_ASSERTION(Get(), "MediaManager singleton?");
NS_ASSERTION(Get()->mMediaThread, "No thread yet");
Get()->mMediaThread->message_loop()->PostTask(std::move(task));
MOZ_ALWAYS_SUCCEEDS(Get()->mMediaThread->Dispatch(std::move(task)));
}
template <typename MozPromiseType, typename FunctionType>
/* static */
RefPtr<MozPromiseType> MediaManager::PostTask(const char* aName,
RefPtr<MozPromiseType> MediaManager::Dispatch(const char* aName,
FunctionType&& aFunction) {
MozPromiseHolder<MozPromiseType> holder;
RefPtr<MozPromiseType> promise = holder.Ensure(aName);
MediaManager::PostTask(NS_NewRunnableFunction(
MediaManager::Dispatch(NS_NewRunnableFunction(
aName, [h = std::move(holder), func = std::forward<FunctionType>(
aFunction)]() mutable { func(h); }));
return promise;
@ -3512,13 +3502,13 @@ void MediaManager::GetPrefs(nsIPrefBranch* aBranch, const char* aData) {
// shutdown here. This is called either on construction, or when a pref has
// changed. The pref observers are disconnected during shutdown.
MOZ_DIAGNOSTIC_ASSERT(!sHasShutdown);
mMediaThread->message_loop()->PostTask(NS_NewRunnableFunction(
MOZ_ALWAYS_SUCCEEDS(mMediaThread->Dispatch(NS_NewRunnableFunction(
"MediaManager::SetFakeDeviceChangeEventsEnabled",
[enable = mPrefs.mFakeDeviceChangeEventOn] {
if (MediaManager* mm = MediaManager::GetIfExists()) {
mm->GetBackend()->SetFakeDeviceChangeEventsEnabled(enable);
}
}));
})));
}
#endif
}
@ -3615,7 +3605,6 @@ void MediaManager::Shutdown() {
mManager->mDeviceListChangeListener.DisconnectIfExists();
}
}
mozilla::ipc::BackgroundChild::CloseForCurrentThread();
// must explicitly do this before dispatching the reply, since the reply
// may kill us with Stop()
mManager->mBackend =
@ -3648,25 +3637,23 @@ void MediaManager::Shutdown() {
#endif
// Release the backend (and call Shutdown()) from within the MediaManager
// thread Don't use MediaManager::PostTask() because we're sHasShutdown=true
// thread Don't use MediaManager::Dispatch() because we're sHasShutdown=true
// here!
auto shutdown = MakeRefPtr<ShutdownTask>(
this, media::NewRunnableFrom([this, self = RefPtr<MediaManager>(this)]() {
this, media::NewRunnableFrom([]() {
LOG("MediaManager shutdown lambda running, releasing MediaManager "
"singleton and thread");
if (mMediaThread) {
mMediaThread->Stop();
}
StaticMutexAutoLock lock(sSingletonMutex);
// Remove async shutdown blocker
media::GetShutdownBarrier()->RemoveBlocker(
sSingleton->mShutdownBlocker);
// we hold a ref to 'self' which is the same as sSingleton
sSingleton = nullptr;
return NS_OK;
}));
mMediaThread->message_loop()->PostTask(shutdown.forget());
MOZ_ALWAYS_SUCCEEDS(mMediaThread->Dispatch(shutdown.forget()));
mMediaThread->BeginShutdown();
mMediaThread->AwaitShutdownAndIdle();
}
void MediaManager::SendPendingGUMRequest() {
@ -3713,7 +3700,7 @@ nsresult MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
} else if (!strcmp(aTopic, "getUserMedia:got-device-permission")) {
MOZ_ASSERT(aSubject);
nsCOMPtr<nsIRunnable> task = do_QueryInterface(aSubject);
MediaManager::PostTask(NewTaskFrom([task] { task->Run(); }));
MediaManager::Dispatch(NewTaskFrom([task] { task->Run(); }));
return NS_OK;
} else if (!strcmp(aTopic, "getUserMedia:privileged:allow") ||
!strcmp(aTopic, "getUserMedia:response:allow")) {
@ -3778,7 +3765,7 @@ nsresult MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
return task->Denied(MediaMgrError::Name::AbortError, u"In shutdown"_ns);
}
// Reuse the same thread to save memory.
MediaManager::PostTask(task.forget());
MediaManager::Dispatch(task.forget());
return NS_OK;
} else if (IsGUMResponseNoAccess(aTopic, gumNoAccessError)) {
@ -4103,7 +4090,7 @@ SourceListener::InitializeAsync() {
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread");
MOZ_DIAGNOSTIC_ASSERT(!mStopped);
return MediaManager::PostTask<SourceListenerPromise>(
return MediaManager::Dispatch<SourceListenerPromise>(
__func__,
[principal = GetPrincipalHandle(),
audioDevice =
@ -4262,7 +4249,7 @@ void SourceListener::StopTrack(MediaTrack* aTrack) {
state.mDisableTimer->Cancel();
MediaManager::PostTask(NewTaskFrom([device = state.mDevice]() {
MediaManager::Dispatch(NewTaskFrom([device = state.mDevice]() {
device->Stop();
device->Deallocate();
}));
@ -4391,7 +4378,7 @@ void SourceListener::SetEnabledFor(MediaTrack* aTrack, bool aEnable) {
nsString inputDeviceGroupId;
state.mDevice->GetRawGroupId(inputDeviceGroupId);
return MediaManager::PostTask<DeviceOperationPromise>(
return MediaManager::Dispatch<DeviceOperationPromise>(
__func__,
[self, device = state.mDevice, aEnable, inputDeviceGroupId](
MozPromiseHolder<DeviceOperationPromise>& h) {
@ -4591,7 +4578,7 @@ SourceListener::ApplyConstraintsToTrack(
return SourceListenerPromise::CreateAndResolve(false, __func__);
}
return MediaManager::PostTask<SourceListenerPromise>(
return MediaManager::Dispatch<SourceListenerPromise>(
__func__, [device = state.mDevice, aConstraints,
isChrome = aCallerType == CallerType::System](
MozPromiseHolder<SourceListenerPromise>& aHolder) mutable {

View File

@ -37,13 +37,10 @@
# include "mtransport/runnable_utils.h"
#endif
// Note, these suck in Windows headers, unfortunately.
#include "base/thread.h"
#include "base/task.h"
class nsIPrefBranch;
namespace mozilla {
class TaskQueue;
namespace dom {
struct MediaStreamConstraints;
struct MediaTrackConstraints;
@ -148,7 +145,7 @@ class MediaManager final : public nsIMediaManagerService, public nsIObserver {
static MediaManager* Get();
static MediaManager* GetIfExists();
static void StartupInit();
static void PostTask(already_AddRefed<Runnable> task);
static void Dispatch(already_AddRefed<Runnable> task);
/**
* Posts an async operation to the media manager thread.
@ -158,7 +155,7 @@ class MediaManager final : public nsIMediaManagerService, public nsIObserver {
* manager thread.
*/
template <typename MozPromiseType, typename FunctionType>
static RefPtr<MozPromiseType> PostTask(const char* aName,
static RefPtr<MozPromiseType> Dispatch(const char* aName,
FunctionType&& aFunction);
#ifdef DEBUG
@ -321,7 +318,7 @@ class MediaManager final : public nsIMediaManagerService, public nsIObserver {
void GetPrefs(nsIPrefBranch* aBranch, const char* aData);
// Make private because we want only one instance of this class
explicit MediaManager(UniquePtr<base::Thread> aMediaThread);
explicit MediaManager(already_AddRefed<TaskQueue> aMediaThread);
~MediaManager() = default;
void Shutdown();
@ -346,7 +343,7 @@ class MediaManager final : public nsIMediaManagerService, public nsIObserver {
nsTArray<RefPtr<dom::GetUserMediaRequest>> mPendingGUMRequest;
// Always exists
const UniquePtr<base::Thread> mMediaThread;
const RefPtr<TaskQueue> mMediaThread;
nsCOMPtr<nsIAsyncShutdownBlocker> mShutdownBlocker;
// ONLY accessed from MediaManagerThread

View File

@ -33,7 +33,7 @@ enum { kVideoTrack = 1, kAudioTrack = 2, kTrackCount };
class MediaEngine {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaEngine)
NS_DECL_OWNINGTHREAD
NS_DECL_OWNINGEVENTTARGET
void AssertIsOnOwningThread() const { NS_ASSERT_OWNINGTHREAD(MediaEngine); }

View File

@ -236,7 +236,7 @@ nsresult MediaEngineDefaultVideoSource::Start() {
MOZ_ASSERT(mState == kAllocated || mState == kStopped);
MOZ_ASSERT(mTrack, "SetTrack() must happen before Start()");
mTimer = NS_NewTimer();
mTimer = NS_NewTimer(GetCurrentSerialEventTarget());
if (!mTimer) {
return NS_ERROR_FAILURE;
}

View File

@ -235,7 +235,7 @@ class MediaEngineSource : public MediaEngineSourceInterface {
static bool IsVideo(dom::MediaSourceEnum aSource);
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaEngineSource)
NS_DECL_OWNINGTHREAD
NS_DECL_OWNINGEVENTTARGET
void AssertIsOnOwningThread() const {
NS_ASSERT_OWNINGTHREAD(MediaEngineSource);

View File

@ -71,7 +71,8 @@ void MediaEngineWebRTC::SetFakeDeviceChangeEventsEnabled(bool aEnable) {
getter_AddRefs(mFakeDeviceChangeEventTimer),
&FakeDeviceChangeEventTimerTick, this,
FAKE_ONDEVICECHANGE_EVENT_PERIOD_IN_MS, nsITimer::TYPE_REPEATING_SLACK,
"MediaEngineWebRTC::mFakeDeviceChangeEventTimer");
"MediaEngineWebRTC::mFakeDeviceChangeEventTimer",
GetCurrentSerialEventTarget());
return;
}
@ -322,6 +323,7 @@ void MediaEngineWebRTC::Shutdown() {
/* static */ void MediaEngineWebRTC::FakeDeviceChangeEventTimerTick(
nsITimer* aTimer, void* aClosure) {
MediaEngineWebRTC* self = static_cast<MediaEngineWebRTC*>(aClosure);
self->AssertIsOnOwningThread();
self->DeviceListChanged();
}