Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/dom/media/systemservices/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 10 kB image not shown  

Quelle  MediaSystemResourceManager.cpp   Sprache: C

 
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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 "mozilla/TaskQueue.h"

#include "MediaSystemResourceManagerChild.h"
#include "MediaSystemResourceClient.h"

#include "mozilla/layers/ImageBridgeChild.h"

#include "MediaSystemResourceManager.h"

namespace mozilla {

using namespace mozilla::ipc;
using namespace mozilla::layers;

/* static */
StaticRefPtr<MediaSystemResourceManager> MediaSystemResourceManager::sSingleton;

/* static */
MediaSystemResourceManager* MediaSystemResourceManager::Get() {
  if (sSingleton) {
    return sSingleton;
  }
  MediaSystemResourceManager::Init();
  return sSingleton;
}

/* static */
void MediaSystemResourceManager::Shutdown() {
  MOZ_ASSERT(InImageBridgeChildThread());
  if (sSingleton) {
    sSingleton->CloseIPC();
    sSingleton = nullptr;
  }
}

/* static */
void MediaSystemResourceManager::Init() {
  RefPtr<ImageBridgeChild> imageBridge = ImageBridgeChild::GetSingleton();
  if (!imageBridge) {
    NS_WARNING("ImageBridge does not exist");
    return;
  }

  if (InImageBridgeChildThread()) {
    if (!sSingleton) {
#ifdef DEBUG
      static int timesCreated = 0;
      timesCreated++;
      MOZ_ASSERT(timesCreated == 1);
#endif
      sSingleton = new MediaSystemResourceManager();
    }
    return;
  }

  ReentrantMonitor barrier MOZ_UNANNOTATED("MediaSystemResourceManager::Init");
  ReentrantMonitorAutoEnter mainThreadAutoMon(barrier);
  bool done = false;

  RefPtr<Runnable> runnable =
      NS_NewRunnableFunction("MediaSystemResourceManager::Init", [&]() {
        if (!sSingleton) {
          sSingleton = new MediaSystemResourceManager();
        }
        ReentrantMonitorAutoEnter childThreadAutoMon(barrier);
        done = true;
        barrier.NotifyAll();
      });

  imageBridge->GetThread()->Dispatch(runnable.forget());

  // should stop the thread until done.
  while (!done) {
    barrier.Wait();
  }
}

MediaSystemResourceManager::MediaSystemResourceManager()
    : mReentrantMonitor("MediaSystemResourceManager.mReentrantMonitor"),
      mShutDown(false),
      mChild(nullptr) {
  MOZ_ASSERT(InImageBridgeChildThread());
  OpenIPC();
}

MediaSystemResourceManager::~MediaSystemResourceManager() {
  MOZ_ASSERT(IsIpcClosed());
}

void MediaSystemResourceManager::OpenIPC() {
  MOZ_ASSERT(InImageBridgeChildThread());
  MOZ_ASSERT(!mChild);

  media::PMediaSystemResourceManagerChild* child =
      ImageBridgeChild::GetSingleton()
          ->SendPMediaSystemResourceManagerConstructor();
  mChild = static_cast<media::MediaSystemResourceManagerChild*>(child);
  mChild->SetManager(this);
}

void MediaSystemResourceManager::CloseIPC() {
  MOZ_ASSERT(InImageBridgeChildThread());

  if (!mChild) {
    return;
  }
  mChild->Destroy();
  mChild = nullptr;
  mShutDown = true;
}

void MediaSystemResourceManager::OnIpcClosed() { mChild = nullptr; }

bool MediaSystemResourceManager::IsIpcClosed() { return mChild ? true : false; }

void MediaSystemResourceManager::Register(MediaSystemResourceClient* aClient) {
  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
  MOZ_ASSERT(aClient);
  MOZ_ASSERT(!mResourceClients.Contains(aClient->mId));

  mResourceClients.InsertOrUpdate(aClient->mId, aClient);
}

void MediaSystemResourceManager::Unregister(
    MediaSystemResourceClient* aClient) {
  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
  MOZ_ASSERT(aClient);
  MOZ_ASSERT(mResourceClients.Contains(aClient->mId));
  MOZ_ASSERT(mResourceClients.Get(aClient->mId) == aClient);

  mResourceClients.Remove(aClient->mId);
}

bool MediaSystemResourceManager::SetListener(
    MediaSystemResourceClient* aClient,
    MediaSystemResourceReservationListener* aListener) {
  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
  MOZ_ASSERT(aClient);

  MediaSystemResourceClient* client = mResourceClients.Get(aClient->mId);
  MOZ_ASSERT(client);

  if (!client) {
    return false;
  }
  // State Check
  if (aClient->mResourceState !=
      MediaSystemResourceClient::RESOURCE_STATE_START) {
    return false;
  }
  aClient->mListener = aListener;
  return true;
}

void MediaSystemResourceManager::Acquire(MediaSystemResourceClient* aClient) {
  MOZ_ASSERT(aClient);
  MOZ_ASSERT(!InImageBridgeChildThread());

  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
  MediaSystemResourceClient* client = mResourceClients.Get(aClient->mId);
  MOZ_ASSERT(client);
  MOZ_ASSERT(client == aClient);

  aClient->mIsSync = false;  // async request

  if (!client) {
    HandleAcquireResult(aClient->mId, false);
    return;
  }
  // State Check
  if (aClient->mResourceState !=
      MediaSystemResourceClient::RESOURCE_STATE_START) {
    HandleAcquireResult(aClient->mId, false);
    return;
  }
  aClient->mResourceState = MediaSystemResourceClient::RESOURCE_STATE_WAITING;
  ImageBridgeChild::GetSingleton()->GetThread()->Dispatch(
      NewRunnableMethod<uint32_t>("MediaSystemResourceManager::DoAcquire"this,
                                  &MediaSystemResourceManager::DoAcquire,
                                  aClient->mId));
}

bool MediaSystemResourceManager::AcquireSyncNoWait(
    MediaSystemResourceClient* aClient) {
  MOZ_ASSERT(aClient);
  MOZ_ASSERT(!InImageBridgeChildThread());

  ReentrantMonitor barrier MOZ_UNANNOTATED(
      "MediaSystemResourceManager::AcquireSyncNoWait");
  ReentrantMonitorAutoEnter autoMon(barrier);
  bool done = false;
  {
    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
    MediaSystemResourceClient* client = mResourceClients.Get(aClient->mId);
    MOZ_ASSERT(client);
    MOZ_ASSERT(client == aClient);

    aClient->mIsSync = true;  // sync request

    if (InImageBridgeChildThread()) {
      HandleAcquireResult(aClient->mId, false);
      return false;
    }
    if (!client || client != aClient) {
      HandleAcquireResult(aClient->mId, false);
      return false;
    }
    // State Check
    if (aClient->mResourceState !=
        MediaSystemResourceClient::RESOURCE_STATE_START) {
      HandleAcquireResult(aClient->mId, false);
      return false;
    }
    // Hold barrier Monitor until acquire task end.
    aClient->mAcquireSyncWaitMonitor = &barrier;
    aClient->mAcquireSyncWaitDone = &done;
    aClient->mResourceState = MediaSystemResourceClient::RESOURCE_STATE_WAITING;
  }

  ImageBridgeChild::GetSingleton()->GetThread()->Dispatch(
      NewRunnableMethod<uint32_t>("MediaSystemResourceManager::DoAcquire"this,
                                  &MediaSystemResourceManager::DoAcquire,
                                  aClient->mId));

  // should stop the thread until done.
  while (!done) {
    barrier.Wait();
  }

  {
    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
    if (aClient->mResourceState !=
        MediaSystemResourceClient::RESOURCE_STATE_ACQUIRED) {
      return false;
    }
    return true;
  }
}

void MediaSystemResourceManager::DoAcquire(uint32_t aId) {
  MOZ_ASSERT(InImageBridgeChildThread());
  if (mShutDown || !mChild) {
    HandleAcquireResult(aId, false);
    return;
  }
  {
    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
    MediaSystemResourceClient* client = mResourceClients.Get(aId);
    MOZ_ASSERT(client);

    if (!client || client->mResourceState !=
                       MediaSystemResourceClient::RESOURCE_STATE_WAITING) {
      HandleAcquireResult(aId, false);
      return;
    }
    MOZ_ASSERT(aId == client->mId);
    bool willWait = !client->mAcquireSyncWaitMonitor ? true : false;
    mChild->SendAcquire(client->mId, client->mResourceType, willWait);
  }
}

void MediaSystemResourceManager::ReleaseResource(
    MediaSystemResourceClient* aClient) {
  MOZ_ASSERT(aClient);
  {
    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
    MediaSystemResourceClient* client = mResourceClients.Get(aClient->mId);
    MOZ_ASSERT(client);
    MOZ_ASSERT(client == aClient);

    if (!client || client != aClient ||
        aClient->mResourceState ==
            MediaSystemResourceClient::RESOURCE_STATE_START ||
        aClient->mResourceState ==
            MediaSystemResourceClient::RESOURCE_STATE_END) {
      aClient->mResourceState = MediaSystemResourceClient::RESOURCE_STATE_END;
      return;
    }

    aClient->mResourceState = MediaSystemResourceClient::RESOURCE_STATE_END;

    ImageBridgeChild::GetSingleton()->GetThread()->Dispatch(
        NewRunnableMethod<uint32_t>(
            "MediaSystemResourceManager::DoRelease"this,
            &MediaSystemResourceManager::DoRelease, aClient->mId));
  }
}

void MediaSystemResourceManager::DoRelease(uint32_t aId) {
  MOZ_ASSERT(InImageBridgeChildThread());
  if (mShutDown || !mChild) {
    return;
  }
  mChild->SendRelease(aId);
}

void MediaSystemResourceManager::RecvResponse(uint32_t aId, bool aSuccess) {
  HandleAcquireResult(aId, aSuccess);
}

void MediaSystemResourceManager::HandleAcquireResult(uint32_t aId,
                                                     bool aSuccess) {
  if (!InImageBridgeChildThread()) {
    ImageBridgeChild::GetSingleton()->GetThread()->Dispatch(
        NewRunnableMethod<uint32_t, bool>(
            "MediaSystemResourceManager::HandleAcquireResult"this,
            &MediaSystemResourceManager::HandleAcquireResult, aId, aSuccess));
    return;
  }

  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
  MediaSystemResourceClient* client = mResourceClients.Get(aId);
  if (!client) {
    // Client was already unregistered.
    return;
  }
  if (client->mResourceState !=
      MediaSystemResourceClient::RESOURCE_STATE_WAITING) {
    return;
  }

  // Update state
  if (aSuccess) {
    client->mResourceState = MediaSystemResourceClient::RESOURCE_STATE_ACQUIRED;
  } else {
    client->mResourceState =
        MediaSystemResourceClient::RESOURCE_STATE_NOT_ACQUIRED;
  }

  if (client->mIsSync) {
    if (client->mAcquireSyncWaitMonitor) {
      // Notify AcquireSync() complete
      MOZ_ASSERT(client->mAcquireSyncWaitDone);
      ReentrantMonitorAutoEnter autoMon(*client->mAcquireSyncWaitMonitor);
      *client->mAcquireSyncWaitDone = true;
      client->mAcquireSyncWaitMonitor->NotifyAll();
      client->mAcquireSyncWaitMonitor = nullptr;
      client->mAcquireSyncWaitDone = nullptr;
    }
  } else {
    // Notify Acquire() result
    if (client->mListener) {
      if (aSuccess) {
        client->mListener->ResourceReserved();
      } else {
        client->mListener->ResourceReserveFailed();
      }
    }
  }
}

}  // namespace mozilla

Messung V0.5
C=90 H=97 G=93

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.