forked from mirrors/gecko-dev
		
	 fde06f6d21
			
		
	
	
		fde06f6d21
		
	
	
	
	
		
			
			Also add some missing namespace qualifications
Done with:
./mach static-analysis check --checks="-*,modernize-concat-nested-namespaces" --fix dom/
./mach clang-format -p $(hg status dom/|grep ^M|awk '{print $2}')
Differential Revision: https://phabricator.services.mozilla.com/D95456
		
	
			
		
			
				
	
	
		
			208 lines
		
	
	
	
		
			6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			208 lines
		
	
	
	
		
			6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- 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/. */
 | |
| 
 | |
| #include <limits>
 | |
| #include "mozilla/Hal.h"
 | |
| #include "ConnectionWorker.h"
 | |
| #include "mozilla/dom/WorkerPrivate.h"
 | |
| #include "mozilla/dom/WorkerRef.h"
 | |
| #include "mozilla/dom/WorkerRunnable.h"
 | |
| 
 | |
| namespace mozilla::dom::network {
 | |
| 
 | |
| class ConnectionProxy final : public hal::NetworkObserver {
 | |
|  public:
 | |
|   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ConnectionProxy)
 | |
| 
 | |
|   static already_AddRefed<ConnectionProxy> Create(
 | |
|       WorkerPrivate* aWorkerPrivate, ConnectionWorker* aConnection) {
 | |
|     RefPtr<ConnectionProxy> proxy = new ConnectionProxy(aConnection);
 | |
| 
 | |
|     RefPtr<StrongWorkerRef> workerRef = StrongWorkerRef::Create(
 | |
|         aWorkerPrivate, "ConnectionProxy", [proxy]() { proxy->Shutdown(); });
 | |
|     if (NS_WARN_IF(!workerRef)) {
 | |
|       return nullptr;
 | |
|     }
 | |
| 
 | |
|     proxy->mWorkerRef = new ThreadSafeWorkerRef(workerRef);
 | |
|     return proxy.forget();
 | |
|   }
 | |
| 
 | |
|   ThreadSafeWorkerRef* WorkerRef() const { return mWorkerRef; }
 | |
| 
 | |
|   // For IObserver - main-thread only.
 | |
|   void Notify(const hal::NetworkInformation& aNetworkInfo) override;
 | |
| 
 | |
|   void Shutdown();
 | |
| 
 | |
|   void Update(ConnectionType aType, bool aIsWifi, uint32_t aDHCPGateway) {
 | |
|     MOZ_ASSERT(mConnection);
 | |
|     MOZ_ASSERT(IsCurrentThreadRunningWorker());
 | |
|     mConnection->Update(aType, aIsWifi, aDHCPGateway, true);
 | |
|   }
 | |
| 
 | |
|  private:
 | |
|   explicit ConnectionProxy(ConnectionWorker* aConnection)
 | |
|       : mConnection(aConnection) {}
 | |
| 
 | |
|   ~ConnectionProxy() = default;
 | |
| 
 | |
|   // Raw pointer because the ConnectionWorker keeps alive the proxy.
 | |
|   // This is touched only on the worker-thread and it's nullified when the
 | |
|   // shutdown procedure starts.
 | |
|   ConnectionWorker* mConnection;
 | |
| 
 | |
|   RefPtr<ThreadSafeWorkerRef> mWorkerRef;
 | |
| };
 | |
| 
 | |
| namespace {
 | |
| 
 | |
| // This class initializes the hal observer on the main-thread.
 | |
| class InitializeRunnable : public WorkerMainThreadRunnable {
 | |
|  private:
 | |
|   // raw pointer because this is a sync runnable.
 | |
|   ConnectionProxy* mProxy;
 | |
|   hal::NetworkInformation& mNetworkInfo;
 | |
| 
 | |
|  public:
 | |
|   InitializeRunnable(WorkerPrivate* aWorkerPrivate, ConnectionProxy* aProxy,
 | |
|                      hal::NetworkInformation& aNetworkInfo)
 | |
|       : WorkerMainThreadRunnable(aWorkerPrivate,
 | |
|                                  "ConnectionWorker :: Initialize"_ns),
 | |
|         mProxy(aProxy),
 | |
|         mNetworkInfo(aNetworkInfo) {
 | |
|     MOZ_ASSERT(aProxy);
 | |
|     aWorkerPrivate->AssertIsOnWorkerThread();
 | |
|   }
 | |
| 
 | |
|   bool MainThreadRun() override {
 | |
|     MOZ_ASSERT(NS_IsMainThread());
 | |
|     hal::RegisterNetworkObserver(mProxy);
 | |
|     hal::GetCurrentNetworkInformation(&mNetworkInfo);
 | |
|     return true;
 | |
|   }
 | |
| };
 | |
| 
 | |
| // This class turns down the hal observer on the main-thread.
 | |
| class ShutdownRunnable : public WorkerMainThreadRunnable {
 | |
|  private:
 | |
|   // raw pointer because this is a sync runnable.
 | |
|   ConnectionProxy* mProxy;
 | |
| 
 | |
|  public:
 | |
|   ShutdownRunnable(WorkerPrivate* aWorkerPrivate, ConnectionProxy* aProxy)
 | |
|       : WorkerMainThreadRunnable(aWorkerPrivate,
 | |
|                                  "ConnectionWorker :: Shutdown"_ns),
 | |
|         mProxy(aProxy) {
 | |
|     MOZ_ASSERT(aProxy);
 | |
|     aWorkerPrivate->AssertIsOnWorkerThread();
 | |
|   }
 | |
| 
 | |
|   bool MainThreadRun() override {
 | |
|     MOZ_ASSERT(NS_IsMainThread());
 | |
|     hal::UnregisterNetworkObserver(mProxy);
 | |
|     return true;
 | |
|   }
 | |
| };
 | |
| 
 | |
| class NotifyRunnable : public WorkerRunnable {
 | |
|  private:
 | |
|   RefPtr<ConnectionProxy> mProxy;
 | |
| 
 | |
|   const ConnectionType mConnectionType;
 | |
|   const bool mIsWifi;
 | |
|   const uint32_t mDHCPGateway;
 | |
| 
 | |
|  public:
 | |
|   NotifyRunnable(WorkerPrivate* aWorkerPrivate, ConnectionProxy* aProxy,
 | |
|                  ConnectionType aType, bool aIsWifi, uint32_t aDHCPGateway)
 | |
|       : WorkerRunnable(aWorkerPrivate),
 | |
|         mProxy(aProxy),
 | |
|         mConnectionType(aType),
 | |
|         mIsWifi(aIsWifi),
 | |
|         mDHCPGateway(aDHCPGateway) {
 | |
|     MOZ_ASSERT(aProxy);
 | |
|     MOZ_ASSERT(NS_IsMainThread());
 | |
|   }
 | |
| 
 | |
|   bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override {
 | |
|     aWorkerPrivate->AssertIsOnWorkerThread();
 | |
|     mProxy->Update(mConnectionType, mIsWifi, mDHCPGateway);
 | |
|     return true;
 | |
|   }
 | |
| };
 | |
| 
 | |
| }  // anonymous namespace
 | |
| 
 | |
| /* static */
 | |
| already_AddRefed<ConnectionWorker> ConnectionWorker::Create(
 | |
|     WorkerPrivate* aWorkerPrivate, ErrorResult& aRv) {
 | |
|   RefPtr<ConnectionWorker> c = new ConnectionWorker();
 | |
|   c->mProxy = ConnectionProxy::Create(aWorkerPrivate, c);
 | |
|   if (!c->mProxy) {
 | |
|     aRv.ThrowTypeError("The Worker thread is shutting down.");
 | |
|     return nullptr;
 | |
|   }
 | |
| 
 | |
|   hal::NetworkInformation networkInfo;
 | |
|   RefPtr<InitializeRunnable> runnable =
 | |
|       new InitializeRunnable(aWorkerPrivate, c->mProxy, networkInfo);
 | |
| 
 | |
|   runnable->Dispatch(Canceling, aRv);
 | |
|   if (NS_WARN_IF(aRv.Failed())) {
 | |
|     return nullptr;
 | |
|   }
 | |
| 
 | |
|   c->Update(static_cast<ConnectionType>(networkInfo.type()),
 | |
|             networkInfo.isWifi(), networkInfo.dhcpGateway(), false);
 | |
|   return c.forget();
 | |
| }
 | |
| 
 | |
| ConnectionWorker::ConnectionWorker() : Connection(nullptr) {
 | |
|   MOZ_ASSERT(IsCurrentThreadRunningWorker());
 | |
| }
 | |
| 
 | |
| ConnectionWorker::~ConnectionWorker() { Shutdown(); }
 | |
| 
 | |
| void ConnectionWorker::ShutdownInternal() {
 | |
|   MOZ_ASSERT(IsCurrentThreadRunningWorker());
 | |
|   mProxy->Shutdown();
 | |
| }
 | |
| 
 | |
| void ConnectionProxy::Notify(const hal::NetworkInformation& aNetworkInfo) {
 | |
|   MOZ_ASSERT(NS_IsMainThread());
 | |
| 
 | |
|   RefPtr<NotifyRunnable> runnable =
 | |
|       new NotifyRunnable(mWorkerRef->Private(), this,
 | |
|                          static_cast<ConnectionType>(aNetworkInfo.type()),
 | |
|                          aNetworkInfo.isWifi(), aNetworkInfo.dhcpGateway());
 | |
|   runnable->Dispatch();
 | |
| }
 | |
| 
 | |
| void ConnectionProxy::Shutdown() {
 | |
|   MOZ_ASSERT(IsCurrentThreadRunningWorker());
 | |
| 
 | |
|   // Already shut down.
 | |
|   if (!mConnection) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   mConnection = nullptr;
 | |
| 
 | |
|   RefPtr<ShutdownRunnable> runnable =
 | |
|       new ShutdownRunnable(mWorkerRef->Private(), this);
 | |
| 
 | |
|   ErrorResult rv;
 | |
|   // This runnable _must_ be executed.
 | |
|   runnable->Dispatch(Killing, rv);
 | |
|   if (NS_WARN_IF(rv.Failed())) {
 | |
|     rv.SuppressException();
 | |
|   }
 | |
| 
 | |
|   mWorkerRef = nullptr;
 | |
| }
 | |
| 
 | |
| }  // namespace mozilla::dom::network
 |