SocketProcessBackgroundChild.cpp (3516B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #include "SocketProcessBackgroundChild.h" 7 #include "SocketProcessLogging.h" 8 9 #include "mozilla/ipc/Endpoint.h" 10 #include "nsThreadUtils.h" 11 12 namespace mozilla::net { 13 14 StaticMutex SocketProcessBackgroundChild::sMutex; 15 StaticRefPtr<SocketProcessBackgroundChild> 16 SocketProcessBackgroundChild::sInstance; 17 StaticRefPtr<nsISerialEventTarget> SocketProcessBackgroundChild::sTaskQueue; 18 19 // static 20 RefPtr<SocketProcessBackgroundChild> 21 SocketProcessBackgroundChild::GetSingleton() { 22 StaticMutexAutoLock lock(sMutex); 23 return sInstance; 24 } 25 26 // static 27 void SocketProcessBackgroundChild::Create( 28 ipc::Endpoint<PSocketProcessBackgroundChild>&& aEndpoint) { 29 if (NS_WARN_IF(!aEndpoint.IsValid())) { 30 MOZ_ASSERT_UNREACHABLE( 31 "Can't create SocketProcessBackgroundChild with invalid endpoint"); 32 return; 33 } 34 35 nsCOMPtr<nsISerialEventTarget> transportQueue; 36 if (NS_WARN_IF(NS_FAILED(NS_CreateBackgroundTaskQueue( 37 "SocketBackgroundChildQueue", getter_AddRefs(transportQueue))))) { 38 return; 39 } 40 41 RefPtr<SocketProcessBackgroundChild> actor = 42 new SocketProcessBackgroundChild(); 43 44 transportQueue->Dispatch(NS_NewRunnableFunction( 45 "BindSocketBackgroundChild", 46 [endpoint = std::move(aEndpoint), actor]() mutable { 47 // We checked endpoint validity before the dispatch, so this cannot 48 // fail. 49 MOZ_ALWAYS_TRUE(endpoint.Bind(actor)); 50 })); 51 52 // Immediately store the actor and queue into the global. 53 // Any messages dispatched to the queue will arrive after it has been bound. 54 LOG(("SocketProcessBackgroundChild::Create")); 55 StaticMutexAutoLock lock(sMutex); 56 MOZ_ASSERT(!sInstance && !sTaskQueue, 57 "Cannot initialize SocketProcessBackgroundChild twice!"); 58 sInstance = actor; 59 sTaskQueue = transportQueue; 60 } 61 62 // static 63 void SocketProcessBackgroundChild::Shutdown() { 64 nsCOMPtr<nsISerialEventTarget> taskQueue = TaskQueue(); 65 if (!taskQueue) { 66 return; 67 } 68 69 taskQueue->Dispatch( 70 NS_NewRunnableFunction("SocketProcessBackgroundChild::Shutdown", []() { 71 LOG(("SocketProcessBackgroundChild::Shutdown")); 72 StaticMutexAutoLock lock(sMutex); 73 sInstance->Close(); 74 sInstance = nullptr; 75 sTaskQueue = nullptr; 76 })); 77 } 78 79 // static 80 already_AddRefed<nsISerialEventTarget> 81 SocketProcessBackgroundChild::TaskQueue() { 82 StaticMutexAutoLock lock(sMutex); 83 return do_AddRef(sTaskQueue); 84 } 85 86 // static 87 nsresult SocketProcessBackgroundChild::WithActor( 88 const char* aName, 89 MoveOnlyFunction<void(SocketProcessBackgroundChild*)> aCallback) { 90 nsCOMPtr<nsISerialEventTarget> taskQueue = TaskQueue(); 91 if (!taskQueue) { 92 return NS_ERROR_NOT_AVAILABLE; 93 } 94 95 return taskQueue->Dispatch(NS_NewRunnableFunction( 96 aName, [callback = std::move(aCallback)]() mutable { 97 RefPtr<SocketProcessBackgroundChild> actor = 98 SocketProcessBackgroundChild::GetSingleton(); 99 if (actor) { 100 callback(actor); 101 } 102 })); 103 } 104 105 SocketProcessBackgroundChild::SocketProcessBackgroundChild() { 106 LOG(("SocketProcessBackgroundChild ctor")); 107 } 108 109 SocketProcessBackgroundChild::~SocketProcessBackgroundChild() { 110 LOG(("SocketProcessBackgroundChild dtor")); 111 } 112 113 } // namespace mozilla::net