/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* 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 "SocketProcessBackgroundChild.h" #include "SocketProcessLogging.h" #include "mozilla/ipc/Endpoint.h" #include "nsThreadUtils.h" namespace mozilla::net { StaticMutex SocketProcessBackgroundChild::sMutex; StaticRefPtr SocketProcessBackgroundChild::sInstance; StaticRefPtr SocketProcessBackgroundChild::sTaskQueue; // static RefPtr SocketProcessBackgroundChild::GetSingleton() { StaticMutexAutoLock lock(sMutex); return sInstance; } // static void SocketProcessBackgroundChild::Create( ipc::Endpoint&& aEndpoint) { if (NS_WARN_IF(!aEndpoint.IsValid())) { MOZ_ASSERT_UNREACHABLE( "Can't create SocketProcessBackgroundChild with invalid endpoint"); return; } nsCOMPtr transportQueue; if (NS_WARN_IF(NS_FAILED(NS_CreateBackgroundTaskQueue( "SocketBackgroundChildQueue", getter_AddRefs(transportQueue))))) { return; } RefPtr actor = new SocketProcessBackgroundChild(); transportQueue->Dispatch(NS_NewRunnableFunction( "BindSocketBackgroundChild", [endpoint = std::move(aEndpoint), actor]() mutable { // We checked endpoint validity before the dispatch, so this cannot // fail. MOZ_ALWAYS_TRUE(endpoint.Bind(actor)); })); // Immediately store the actor and queue into the global. // Any messages dispatched to the queue will arrive after it has been bound. LOG(("SocketProcessBackgroundChild::Create")); StaticMutexAutoLock lock(sMutex); MOZ_ASSERT(!sInstance && !sTaskQueue, "Cannot initialize SocketProcessBackgroundChild twice!"); sInstance = actor; sTaskQueue = transportQueue; } // static void SocketProcessBackgroundChild::Shutdown() { nsCOMPtr taskQueue = TaskQueue(); if (!taskQueue) { return; } taskQueue->Dispatch( NS_NewRunnableFunction("SocketProcessBackgroundChild::Shutdown", []() { LOG(("SocketProcessBackgroundChild::Shutdown")); StaticMutexAutoLock lock(sMutex); sInstance->Close(); sInstance = nullptr; sTaskQueue = nullptr; })); } // static already_AddRefed SocketProcessBackgroundChild::TaskQueue() { StaticMutexAutoLock lock(sMutex); return do_AddRef(sTaskQueue); } // static nsresult SocketProcessBackgroundChild::WithActor( const char* aName, MoveOnlyFunction aCallback) { nsCOMPtr taskQueue = TaskQueue(); if (!taskQueue) { return NS_ERROR_NOT_AVAILABLE; } return taskQueue->Dispatch(NS_NewRunnableFunction( aName, [callback = std::move(aCallback)]() mutable { RefPtr actor = SocketProcessBackgroundChild::GetSingleton(); if (actor) { callback(actor); } })); } SocketProcessBackgroundChild::SocketProcessBackgroundChild() { LOG(("SocketProcessBackgroundChild ctor")); } SocketProcessBackgroundChild::~SocketProcessBackgroundChild() { LOG(("SocketProcessBackgroundChild dtor")); } } // namespace mozilla::net