LCOV - code coverage report
Current view: top level - dom/file/ipc - IPCBlobInputStreamThread.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 2 84 2.4 %
Date: 2017-07-14 16:53:18 Functions: 0 22 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "IPCBlobInputStreamThread.h"
       8             : 
       9             : #include "mozilla/StaticMutex.h"
      10             : #include "mozilla/SystemGroup.h"
      11             : #include "mozilla/TaskCategory.h"
      12             : #include "mozilla/ipc/BackgroundChild.h"
      13             : #include "mozilla/ipc/PBackgroundChild.h"
      14             : #include "nsIIPCBackgroundChildCreateCallback.h"
      15             : #include "nsXPCOMPrivate.h"
      16             : 
      17             : namespace mozilla {
      18             : 
      19             : using namespace ipc;
      20             : 
      21             : namespace dom {
      22             : 
      23             : namespace {
      24             : 
      25           3 : StaticMutex gIPCBlobThreadMutex;
      26           3 : StaticRefPtr<IPCBlobInputStreamThread> gIPCBlobThread;
      27             : bool gShutdownHasStarted = false;
      28             : 
      29           0 : class ThreadInitializeRunnable final : public Runnable
      30             : {
      31             : public:
      32           0 :   ThreadInitializeRunnable() : Runnable("dom::ThreadInitializeRunnable") {}
      33             : 
      34             :   NS_IMETHOD
      35           0 :   Run() override
      36             :   {
      37           0 :      mozilla::StaticMutexAutoLock lock(gIPCBlobThreadMutex);
      38           0 :      MOZ_ASSERT(gIPCBlobThread);
      39           0 :      gIPCBlobThread->Initialize();
      40           0 :      return NS_OK;
      41             :   }
      42             : };
      43             : 
      44             : class MigrateActorRunnable final : public Runnable
      45             :                                  , public nsIIPCBackgroundChildCreateCallback
      46             : {
      47             : public:
      48             :   NS_DECL_ISUPPORTS_INHERITED
      49             : 
      50           0 :   explicit MigrateActorRunnable(IPCBlobInputStreamChild* aActor)
      51           0 :     : Runnable("dom::MigrateActorRunnable")
      52           0 :     , mActor(aActor)
      53             :   {
      54           0 :     MOZ_ASSERT(mActor);
      55           0 :   }
      56             : 
      57             :   NS_IMETHOD
      58           0 :   Run() override
      59             :   {
      60           0 :     BackgroundChild::GetOrCreateForCurrentThread(this);
      61           0 :     return NS_OK;
      62             :   }
      63             : 
      64             :   void
      65           0 :   ActorFailed() override
      66             :   {
      67             :     // We cannot continue. We are probably shutting down.
      68           0 :   }
      69             : 
      70             :   void
      71           0 :   ActorCreated(mozilla::ipc::PBackgroundChild* aActor) override
      72             :   {
      73           0 :     MOZ_ASSERT(mActor->State() == IPCBlobInputStreamChild::eInactiveMigrating);
      74             : 
      75           0 :     if (aActor->SendPIPCBlobInputStreamConstructor(mActor, mActor->ID(),
      76           0 :                                                    mActor->Size())) {
      77             :       // We need manually to increase the reference for this actor because the
      78             :       // IPC allocator method is not triggered. The Release() is called by IPDL
      79             :       // when the actor is deleted.
      80           0 :       mActor.get()->AddRef();
      81           0 :       mActor->Migrated();
      82             :     }
      83           0 :   }
      84             : 
      85             : private:
      86           0 :   ~MigrateActorRunnable() = default;
      87             : 
      88             :   RefPtr<IPCBlobInputStreamChild> mActor;
      89             : };
      90             : 
      91           0 : NS_IMPL_ISUPPORTS_INHERITED(MigrateActorRunnable, Runnable,
      92             :                   nsIIPCBackgroundChildCreateCallback)
      93             : 
      94             : } // anonymous
      95             : 
      96           0 : NS_IMPL_ISUPPORTS(IPCBlobInputStreamThread, nsIObserver)
      97             : 
      98             : /* static */ bool
      99           0 : IPCBlobInputStreamThread::IsOnFileEventTarget(nsIEventTarget* aEventTarget)
     100             : {
     101           0 :   MOZ_ASSERT(aEventTarget);
     102             : 
     103           0 :   mozilla::StaticMutexAutoLock lock(gIPCBlobThreadMutex);
     104           0 :   return gIPCBlobThread && aEventTarget == gIPCBlobThread->mThread;
     105             : }
     106             : 
     107             : /* static */ IPCBlobInputStreamThread*
     108           0 : IPCBlobInputStreamThread::GetOrCreate()
     109             : {
     110           0 :   mozilla::StaticMutexAutoLock lock(gIPCBlobThreadMutex);
     111             : 
     112           0 :   if (gShutdownHasStarted) {
     113           0 :     return nullptr;
     114             :   }
     115             : 
     116           0 :   if (!gIPCBlobThread) {
     117           0 :     gIPCBlobThread = new IPCBlobInputStreamThread();
     118           0 :     gIPCBlobThread->Initialize();
     119             :   }
     120             : 
     121           0 :   return gIPCBlobThread;
     122             : }
     123             : 
     124             : void
     125           0 : IPCBlobInputStreamThread::Initialize()
     126             : {
     127           0 :   if (!NS_IsMainThread()) {
     128           0 :     RefPtr<Runnable> runnable = new ThreadInitializeRunnable();
     129           0 :     SystemGroup::Dispatch("IPCBlobInputStreamThread::Initialize",
     130             :                           TaskCategory::Other,
     131           0 :                           runnable.forget());
     132           0 :     return;
     133             :   }
     134             : 
     135           0 :   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
     136           0 :   if (NS_WARN_IF(!obs)) {
     137           0 :     return;
     138             :   }
     139             : 
     140             :   nsresult rv =
     141           0 :     obs->AddObserver(this, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID, false);
     142           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     143           0 :     return;
     144             :   }
     145             : 
     146           0 :   nsCOMPtr<nsIThread> thread;
     147           0 :   rv = NS_NewNamedThread("DOM File", getter_AddRefs(thread));
     148           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     149           0 :     return;
     150             :   }
     151             : 
     152           0 :   mThread = thread;
     153             : 
     154           0 :   if (!mPendingActors.IsEmpty()) {
     155           0 :     for (uint32_t i = 0; i < mPendingActors.Length(); ++i) {
     156           0 :       MigrateActorInternal(mPendingActors[i]);
     157             :     }
     158             : 
     159           0 :     mPendingActors.Clear();
     160             :   }
     161             : }
     162             : 
     163             : NS_IMETHODIMP
     164           0 : IPCBlobInputStreamThread::Observe(nsISupports* aSubject,
     165             :                                   const char* aTopic,
     166             :                                   const char16_t* aData)
     167             : {
     168           0 :   MOZ_ASSERT(!strcmp(aTopic, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID));
     169             : 
     170           0 :   mozilla::StaticMutexAutoLock lock(gIPCBlobThreadMutex);
     171             : 
     172           0 :   if (mThread) {
     173           0 :     mThread->Shutdown();
     174           0 :     mThread = nullptr;
     175             :   }
     176             : 
     177           0 :   gShutdownHasStarted = true;
     178           0 :   gIPCBlobThread = nullptr;
     179             : 
     180           0 :   return NS_OK;
     181             : }
     182             : 
     183             : void
     184           0 : IPCBlobInputStreamThread::MigrateActor(IPCBlobInputStreamChild* aActor)
     185             : {
     186           0 :   MOZ_ASSERT(aActor->State() == IPCBlobInputStreamChild::eInactiveMigrating);
     187             : 
     188           0 :   mozilla::StaticMutexAutoLock lock(gIPCBlobThreadMutex);
     189             : 
     190           0 :   if (gShutdownHasStarted) {
     191           0 :     return;
     192             :   }
     193             : 
     194           0 :   if (!mThread) {
     195             :     // The thread is not initialized yet.
     196           0 :     mPendingActors.AppendElement(aActor);
     197           0 :     return;
     198             :   }
     199             : 
     200           0 :   MigrateActorInternal(aActor);
     201             : }
     202             : 
     203             : void
     204           0 : IPCBlobInputStreamThread::MigrateActorInternal(IPCBlobInputStreamChild* aActor)
     205             : {
     206           0 :   RefPtr<Runnable> runnable = new MigrateActorRunnable(aActor);
     207           0 :   mThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
     208           0 : }
     209             : 
     210             : } // dom namespace
     211             : } // mozilla namespace

Generated by: LCOV version 1.13