LCOV - code coverage report
Current view: top level - dom/media/systemservices - MediaSystemResourceManager.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 1 204 0.5 %
Date: 2017-07-14 16:53:18 Functions: 0 21 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim:set ts=2 sw=2 sts=2 et cindent: */
       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 file,
       5             :  * You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "mozilla/TaskQueue.h"
       8             : 
       9             : #include "gfxPrefs.h"
      10             : #include "MediaSystemResourceManagerChild.h"
      11             : #include "mozilla/layers/ImageBridgeChild.h"
      12             : 
      13             : #include "MediaSystemResourceManager.h"
      14             : 
      15             : namespace mozilla {
      16             : 
      17             : using namespace mozilla::ipc;
      18             : using namespace mozilla::layers;
      19             : 
      20           3 : /* static */ StaticRefPtr<MediaSystemResourceManager> MediaSystemResourceManager::sSingleton;
      21             : 
      22             : /* static */ MediaSystemResourceManager*
      23           0 : MediaSystemResourceManager::Get()
      24             : {
      25           0 :   if (sSingleton) {
      26           0 :     return sSingleton;
      27             :   }
      28           0 :   MediaSystemResourceManager::Init();
      29           0 :   return sSingleton;
      30             : }
      31             : 
      32             : /* static */ void
      33           0 : MediaSystemResourceManager::Shutdown()
      34             : {
      35           0 :   MOZ_ASSERT(InImageBridgeChildThread());
      36           0 :   if (sSingleton) {
      37           0 :     sSingleton->CloseIPC();
      38           0 :     sSingleton = nullptr;
      39             :   }
      40           0 : }
      41             : 
      42             : /* static */ void
      43           0 : MediaSystemResourceManager::Init()
      44             : {
      45           0 :   RefPtr<ImageBridgeChild> imageBridge = ImageBridgeChild::GetSingleton();
      46           0 :   if (!imageBridge) {
      47           0 :     NS_WARNING("ImageBridge does not exist");
      48           0 :     return;
      49             :   }
      50             : 
      51           0 :   if (InImageBridgeChildThread()) {
      52           0 :     if (!sSingleton) {
      53             : #ifdef DEBUG
      54             :       static int timesCreated = 0;
      55           0 :       timesCreated++;
      56           0 :       MOZ_ASSERT(timesCreated == 1);
      57             : #endif
      58           0 :       sSingleton = new MediaSystemResourceManager();
      59             :     }
      60           0 :     return;
      61             :   }
      62             : 
      63           0 :   ReentrantMonitor barrier("MediaSystemResourceManager::Init");
      64           0 :   ReentrantMonitorAutoEnter mainThreadAutoMon(barrier);
      65           0 :   bool done = false;
      66             : 
      67             :   RefPtr<Runnable> runnable =
      68           0 :     NS_NewRunnableFunction("MediaSystemResourceManager::Init", [&]() {
      69           0 :       if (!sSingleton) {
      70           0 :         sSingleton = new MediaSystemResourceManager();
      71             :       }
      72           0 :       ReentrantMonitorAutoEnter childThreadAutoMon(barrier);
      73           0 :       done = true;
      74           0 :       barrier.NotifyAll();
      75           0 :     });
      76             : 
      77           0 :   imageBridge->GetMessageLoop()->PostTask(runnable.forget());
      78             : 
      79             :   // should stop the thread until done.
      80           0 :   while (!done) {
      81           0 :     barrier.Wait();
      82             :   }
      83             : }
      84             : 
      85           0 : MediaSystemResourceManager::MediaSystemResourceManager()
      86             :   : mReentrantMonitor("MediaSystemResourceManager.mReentrantMonitor")
      87             :   , mShutDown(false)
      88           0 :   , mChild(nullptr)
      89             : {
      90           0 :   MOZ_ASSERT(InImageBridgeChildThread());
      91           0 :   OpenIPC();
      92           0 : }
      93             : 
      94           0 : MediaSystemResourceManager::~MediaSystemResourceManager()
      95             : {
      96           0 :   MOZ_ASSERT(IsIpcClosed());
      97           0 : }
      98             : 
      99             : void
     100           0 : MediaSystemResourceManager::OpenIPC()
     101             : {
     102           0 :   MOZ_ASSERT(InImageBridgeChildThread());
     103           0 :   MOZ_ASSERT(!mChild);
     104             : 
     105             :   media::PMediaSystemResourceManagerChild* child =
     106           0 :     ImageBridgeChild::GetSingleton()->SendPMediaSystemResourceManagerConstructor();
     107           0 :   mChild = static_cast<media::MediaSystemResourceManagerChild*>(child);
     108           0 :   mChild->SetManager(this);
     109           0 : }
     110             : 
     111             : void
     112           0 : MediaSystemResourceManager::CloseIPC()
     113             : {
     114           0 :   MOZ_ASSERT(InImageBridgeChildThread());
     115             : 
     116           0 :   if (!mChild) {
     117           0 :     return;
     118             :   }
     119           0 :   mChild->Destroy();
     120           0 :   mChild = nullptr;
     121           0 :   mShutDown = true;
     122             : }
     123             : 
     124             : void
     125           0 : MediaSystemResourceManager::OnIpcClosed()
     126             : {
     127           0 :   mChild = nullptr;
     128           0 : }
     129             : 
     130             : bool
     131           0 : MediaSystemResourceManager::IsIpcClosed()
     132             : {
     133           0 :   return mChild ? true : false;
     134             : }
     135             : 
     136             : void
     137           0 : MediaSystemResourceManager::Register(MediaSystemResourceClient* aClient)
     138             : {
     139           0 :   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     140           0 :   MOZ_ASSERT(aClient);
     141           0 :   MOZ_ASSERT(!mResourceClients.Get(aClient->mId));
     142             : 
     143           0 :   mResourceClients.Put(aClient->mId, aClient);
     144           0 : }
     145             : 
     146             : void
     147           0 : MediaSystemResourceManager::Unregister(MediaSystemResourceClient* aClient)
     148             : {
     149           0 :   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     150           0 :   MOZ_ASSERT(aClient);
     151           0 :   MOZ_ASSERT(mResourceClients.Get(aClient->mId));
     152           0 :   MOZ_ASSERT(mResourceClients.Get(aClient->mId) == aClient);
     153             : 
     154           0 :   mResourceClients.Remove(aClient->mId);
     155           0 : }
     156             : 
     157             : bool
     158           0 : MediaSystemResourceManager::SetListener(MediaSystemResourceClient* aClient,
     159             :                                   MediaSystemResourceReservationListener* aListener)
     160             : {
     161           0 :   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     162           0 :   MOZ_ASSERT(aClient);
     163             : 
     164           0 :   MediaSystemResourceClient* client = mResourceClients.Get(aClient->mId);
     165           0 :   MOZ_ASSERT(client);
     166             : 
     167           0 :   if (!client) {
     168           0 :     return false;
     169             :   }
     170             :   // State Check
     171           0 :   if (aClient->mResourceState != MediaSystemResourceClient::RESOURCE_STATE_START) {
     172           0 :     return false;
     173             :   }
     174           0 :   aClient->mListener = aListener;
     175           0 :   return true;
     176             : }
     177             : 
     178             : void
     179           0 : MediaSystemResourceManager::Acquire(MediaSystemResourceClient* aClient)
     180             : {
     181           0 :   MOZ_ASSERT(aClient);
     182           0 :   MOZ_ASSERT(!InImageBridgeChildThread());
     183             : 
     184           0 :   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     185           0 :   MediaSystemResourceClient* client = mResourceClients.Get(aClient->mId);
     186           0 :   MOZ_ASSERT(client);
     187           0 :   MOZ_ASSERT(client == aClient);
     188             : 
     189           0 :   aClient->mIsSync = false; // async request
     190             : 
     191           0 :   if (!client) {
     192           0 :     HandleAcquireResult(aClient->mId, false);
     193           0 :     return;
     194             :   }
     195             :   // State Check
     196           0 :   if (aClient->mResourceState != MediaSystemResourceClient::RESOURCE_STATE_START) {
     197           0 :     HandleAcquireResult(aClient->mId, false);
     198           0 :     return;
     199             :   }
     200           0 :   aClient->mResourceState = MediaSystemResourceClient::RESOURCE_STATE_WAITING;
     201           0 :   ImageBridgeChild::GetSingleton()->GetMessageLoop()->PostTask(
     202           0 :     NewRunnableMethod<uint32_t>("MediaSystemResourceManager::DoAcquire",
     203             :                                 this,
     204             :                                 &MediaSystemResourceManager::DoAcquire,
     205           0 :                                 aClient->mId));
     206             : }
     207             : 
     208             : bool
     209           0 : MediaSystemResourceManager::AcquireSyncNoWait(MediaSystemResourceClient* aClient)
     210             : {
     211           0 :   MOZ_ASSERT(aClient);
     212           0 :   MOZ_ASSERT(!InImageBridgeChildThread());
     213             : 
     214           0 :   ReentrantMonitor barrier("MediaSystemResourceManager::AcquireSyncNoWait");
     215           0 :   ReentrantMonitorAutoEnter autoMon(barrier);
     216           0 :   bool done = false;
     217             :   {
     218           0 :     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     219           0 :     MediaSystemResourceClient* client = mResourceClients.Get(aClient->mId);
     220           0 :     MOZ_ASSERT(client);
     221           0 :     MOZ_ASSERT(client == aClient);
     222             : 
     223           0 :     aClient->mIsSync = true; // sync request
     224             : 
     225           0 :     if (InImageBridgeChildThread()) {
     226           0 :       HandleAcquireResult(aClient->mId, false);
     227           0 :       return false;
     228             :     }
     229           0 :     if (!client || client != aClient) {
     230           0 :       HandleAcquireResult(aClient->mId, false);
     231           0 :       return false;
     232             :     }
     233             :     // State Check
     234           0 :     if (aClient->mResourceState != MediaSystemResourceClient::RESOURCE_STATE_START) {
     235           0 :       HandleAcquireResult(aClient->mId, false);
     236           0 :       return false;
     237             :     }
     238             :     // Hold barrier Monitor until acquire task end.
     239           0 :     aClient->mAcquireSyncWaitMonitor = &barrier;
     240           0 :     aClient->mAcquireSyncWaitDone = &done;
     241           0 :     aClient->mResourceState = MediaSystemResourceClient::RESOURCE_STATE_WAITING;
     242             :   }
     243             : 
     244           0 :   ImageBridgeChild::GetSingleton()->GetMessageLoop()->PostTask(
     245           0 :     NewRunnableMethod<uint32_t>("MediaSystemResourceManager::DoAcquire",
     246             :                                 this,
     247             :                                 &MediaSystemResourceManager::DoAcquire,
     248           0 :                                 aClient->mId));
     249             : 
     250             :   // should stop the thread until done.
     251           0 :   while (!done) {
     252           0 :     barrier.Wait();
     253             :   }
     254             : 
     255             :   {
     256           0 :     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     257           0 :     if (aClient->mResourceState != MediaSystemResourceClient::RESOURCE_STATE_ACQUIRED) {
     258           0 :       return false;
     259             :     }
     260           0 :     return true;
     261             :   }
     262             : }
     263             : 
     264             : void
     265           0 : MediaSystemResourceManager::DoAcquire(uint32_t aId)
     266             : {
     267           0 :   MOZ_ASSERT(InImageBridgeChildThread());
     268           0 :   if (mShutDown || !mChild) {
     269           0 :     HandleAcquireResult(aId, false);
     270           0 :     return;
     271             :   }
     272             :   {
     273           0 :     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     274           0 :     MediaSystemResourceClient* client = mResourceClients.Get(aId);
     275           0 :     MOZ_ASSERT(client);
     276             : 
     277           0 :     if (!client ||
     278           0 :         client->mResourceState != MediaSystemResourceClient::RESOURCE_STATE_WAITING) {
     279           0 :       HandleAcquireResult(aId, false);
     280           0 :       return;
     281             :     }
     282           0 :     MOZ_ASSERT(aId == client->mId);
     283           0 :     bool willWait = !client->mAcquireSyncWaitMonitor ? true : false;
     284           0 :     mChild->SendAcquire(client->mId,
     285             :                         client->mResourceType,
     286           0 :                         willWait);
     287             :   }
     288             : }
     289             : 
     290             : void
     291           0 : MediaSystemResourceManager::ReleaseResource(MediaSystemResourceClient* aClient)
     292             : {
     293           0 :   MOZ_ASSERT(aClient);
     294             :   {
     295           0 :     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     296           0 :     MediaSystemResourceClient* client = mResourceClients.Get(aClient->mId);
     297           0 :     MOZ_ASSERT(client);
     298           0 :     MOZ_ASSERT(client == aClient);
     299             : 
     300           0 :     if (!client ||
     301           0 :         client != aClient ||
     302           0 :         aClient->mResourceState == MediaSystemResourceClient::RESOURCE_STATE_START ||
     303           0 :         aClient->mResourceState == MediaSystemResourceClient::RESOURCE_STATE_END) {
     304             : 
     305           0 :       aClient->mResourceState = MediaSystemResourceClient::RESOURCE_STATE_END;
     306           0 :       return;
     307             :     }
     308             : 
     309           0 :     aClient->mResourceState = MediaSystemResourceClient::RESOURCE_STATE_END;
     310             : 
     311           0 :     ImageBridgeChild::GetSingleton()->GetMessageLoop()->PostTask(
     312           0 :       NewRunnableMethod<uint32_t>("MediaSystemResourceManager::DoRelease",
     313             :                                   this,
     314             :                                   &MediaSystemResourceManager::DoRelease,
     315           0 :                                   aClient->mId));
     316             :   }
     317             : }
     318             : 
     319             : void
     320           0 : MediaSystemResourceManager::DoRelease(uint32_t aId)
     321             : {
     322           0 :   MOZ_ASSERT(InImageBridgeChildThread());
     323           0 :   if (mShutDown || !mChild) {
     324           0 :     return;
     325             :   }
     326           0 :   mChild->SendRelease(aId);
     327             : }
     328             : 
     329             : void
     330           0 : MediaSystemResourceManager::RecvResponse(uint32_t aId, bool aSuccess)
     331             : {
     332           0 :   HandleAcquireResult(aId, aSuccess);
     333           0 : }
     334             : 
     335             : void
     336           0 : MediaSystemResourceManager::HandleAcquireResult(uint32_t aId, bool aSuccess)
     337             : {
     338           0 :   if (!InImageBridgeChildThread()) {
     339           0 :     ImageBridgeChild::GetSingleton()->GetMessageLoop()->PostTask(
     340           0 :       NewRunnableMethod<uint32_t, bool>(
     341             :         "MediaSystemResourceManager::HandleAcquireResult",
     342             :         this,
     343             :         &MediaSystemResourceManager::HandleAcquireResult,
     344             :         aId,
     345           0 :         aSuccess));
     346           0 :     return;
     347             :   }
     348             : 
     349           0 :   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     350           0 :   MediaSystemResourceClient* client = mResourceClients.Get(aId);
     351           0 :   if (!client) {
     352             :     // Client was already unregistered.
     353           0 :     return;
     354             :   }
     355           0 :   if (client->mResourceState != MediaSystemResourceClient::RESOURCE_STATE_WAITING) {
     356           0 :     return;
     357             :   }
     358             : 
     359             :   // Update state
     360           0 :   if (aSuccess) {
     361           0 :     client->mResourceState = MediaSystemResourceClient::RESOURCE_STATE_ACQUIRED;
     362             :   } else {
     363           0 :     client->mResourceState = MediaSystemResourceClient::RESOURCE_STATE_NOT_ACQUIRED;
     364             :   }
     365             : 
     366           0 :   if (client->mIsSync) {
     367           0 :     if (client->mAcquireSyncWaitMonitor) {
     368             :       // Notify AcquireSync() complete
     369           0 :       MOZ_ASSERT(client->mAcquireSyncWaitDone);
     370           0 :       ReentrantMonitorAutoEnter autoMon(*client->mAcquireSyncWaitMonitor);
     371           0 :       *client->mAcquireSyncWaitDone = true;
     372           0 :       client->mAcquireSyncWaitMonitor->NotifyAll();
     373           0 :       client->mAcquireSyncWaitMonitor = nullptr;
     374           0 :       client->mAcquireSyncWaitDone = nullptr;
     375             :     }
     376             :   } else {
     377             :     // Notify Acquire() result
     378           0 :     if (client->mListener) {
     379           0 :       if (aSuccess) {
     380           0 :         client->mListener->ResourceReserved();
     381             :       } else {
     382           0 :        client->mListener->ResourceReserveFailed();
     383             :       }
     384             :     }
     385             :   }
     386             : }
     387             : 
     388             : } // namespace mozilla

Generated by: LCOV version 1.13