Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quellcode-Bibliothek StreamList.cpp   Sprache: unbekannt

 
Spracherkennung für: .cpp Download desUnknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

/* 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/dom/cache/StreamList.h"

#include <algorithm>

#include "mozilla/dom/cache/CacheStreamControlParent.h"
#include "mozilla/dom/cache/Context.h"
#include "mozilla/dom/cache/Manager.h"
#include "nsIInputStream.h"

namespace mozilla::dom::cache {

namespace {

auto MatchById(const nsID& aId) {
  return [aId](const auto& entry) { return entry.mId == aId; };
}

}  // namespace

StreamList::StreamList(SafeRefPtr<Manager> aManager,
                       SafeRefPtr<Context> aContext)
    : mManager(std::move(aManager)),
      mContext(std::move(aContext)),
      mCacheId(INVALID_CACHE_ID),
      mStreamControl(nullptr),
      mActivated(false) {
  MOZ_DIAGNOSTIC_ASSERT(mManager);
}

Manager& StreamList::GetManager() const {
  MOZ_DIAGNOSTIC_ASSERT(mManager);
  return *mManager;
}

bool StreamList::ShouldOpenStreamFor(const nsID& aId) const {
  NS_ASSERT_OWNINGTHREAD(StreamList);

  return std::any_of(mList.cbegin(), mList.cend(), MatchById(aId));
}

void StreamList::SetStreamControl(CacheStreamControlParent* aStreamControl) {
  NS_ASSERT_OWNINGTHREAD(StreamList);
  MOZ_DIAGNOSTIC_ASSERT(aStreamControl);

  // For cases where multiple streams are serialized for a single list
  // then the control will get passed multiple times.  This is ok, but
  // it should be the same control each time.
  if (mStreamControl) {
    MOZ_DIAGNOSTIC_ASSERT(aStreamControl == mStreamControl);
    return;
  }

  mStreamControl = aStreamControl;
  mStreamControl->SetStreamList(SafeRefPtrFromThis());
}

void StreamList::RemoveStreamControl(CacheStreamControlParent* aStreamControl) {
  NS_ASSERT_OWNINGTHREAD(StreamList);
  MOZ_DIAGNOSTIC_ASSERT(mStreamControl);
  MOZ_DIAGNOSTIC_ASSERT(mStreamControl == aStreamControl);
  mStreamControl = nullptr;
}

void StreamList::Activate(CacheId aCacheId) {
  NS_ASSERT_OWNINGTHREAD(StreamList);
  MOZ_DIAGNOSTIC_ASSERT(!mActivated);
  MOZ_DIAGNOSTIC_ASSERT(mCacheId == INVALID_CACHE_ID);
  mActivated = true;
  mCacheId = aCacheId;

  mContext->AddActivity(*this);

  mManager->AddRefCacheId(mCacheId);
  mManager->AddStreamList(*this);

  for (uint32_t i = 0; i < mList.Length(); ++i) {
    mManager->AddRefBodyId(mList[i].mId);
  }
}

void StreamList::Add(const nsID& aId, nsCOMPtr<nsIInputStream>&& aStream) {
  // All streams should be added on IO thread before we set the stream
  // control on the owning IPC thread.
  MOZ_DIAGNOSTIC_ASSERT(!mStreamControl);

  // Removal of the stream will be triggered when the stream is closed,
  // which happens only once, so let's ensure nobody adds us twice.
  MOZ_ASSERT_DEBUG_OR_FUZZING(
      std::find_if(mList.begin(), mList.end(), MatchById(aId)) == mList.end());

  mList.EmplaceBack(aId, std::move(aStream));
}

already_AddRefed<nsIInputStream> StreamList::Extract(const nsID& aId) {
  NS_ASSERT_OWNINGTHREAD(StreamList);

  const auto it = std::find_if(mList.begin(), mList.end(), MatchById(aId));

  // Note that if the stream has not been opened with OpenMode::Eager we will
  // find it nullptr here and it will have to be opened by the consumer.

  return it != mList.end() ? it->mStream.forget() : nullptr;
}

void StreamList::NoteClosed(const nsID& aId) {
  NS_ASSERT_OWNINGTHREAD(StreamList);

  const auto it = std::find_if(mList.begin(), mList.end(), MatchById(aId));
  if (it != mList.end()) {
    MOZ_ASSERT(!it->mStream, "We expect to find mStream already extracted.");
    mList.RemoveElementAt(it);
    mManager->ReleaseBodyId(aId);
  }

  if (mList.IsEmpty() && mStreamControl) {
    mStreamControl->Shutdown();
  }
}

void StreamList::NoteClosedAll() {
  NS_ASSERT_OWNINGTHREAD(StreamList);
  for (uint32_t i = 0; i < mList.Length(); ++i) {
    mManager->ReleaseBodyId(mList[i].mId);
  }
  mList.Clear();

  if (mStreamControl) {
    mStreamControl->Shutdown();
  }
}

void StreamList::CloseAll() {
  NS_ASSERT_OWNINGTHREAD(StreamList);
  SafeRefPtr<StreamList> kungFuDeathGrip = SafeRefPtrFromThis();

  if (mStreamControl && mStreamControl->CanSend()) {
    // CloseAll will kick off everything needed for shutdown.
    // mStreamControl may go away immediately or async.
    mStreamControl->CloseAll();
  } else {
    // We cannot interact with the child, let's just clear our lists of
    // streams to unblock shutdown.
    if (NS_WARN_IF(mStreamControl)) {
      // TODO: Check if this case is actually possible. We might see a late
      // delivery of the CSCP::ActorDestroy? What would that mean for CanSend?
      mStreamControl->LostIPCCleanup(SafeRefPtrFromThis());
      mStreamControl = nullptr;
    } else {
      NoteClosedAll();
    }
  }
}

void StreamList::Cancel() {
  NS_ASSERT_OWNINGTHREAD(StreamList);
  CloseAll();
}

bool StreamList::MatchesCacheId(CacheId aCacheId) const {
  NS_ASSERT_OWNINGTHREAD(StreamList);
  return aCacheId == mCacheId;
}

void StreamList::DoStringify(nsACString& aData) {
  aData.Append("StreamList "_ns + kStringifyStartInstance +
               //
               "List:"_ns +
               IntToCString(static_cast<uint64_t>(mList.Length())) +
               kStringifyDelimiter +
               //
               "Activated:"_ns + IntToCString(mActivated) + ")"_ns +
               kStringifyDelimiter +
               //
               "Manager:"_ns + IntToCString(static_cast<bool>(mManager)));
  if (mManager) {
    aData.Append(" "_ns);
    mManager->Stringify(aData);
  }
  aData.Append(kStringifyDelimiter +
               //
               "Context:"_ns + IntToCString(static_cast<bool>(mContext)));
  if (mContext) {
    aData.Append(" "_ns);
    mContext->Stringify(aData);
  }
  aData.Append(kStringifyEndInstance);
}

StreamList::~StreamList() {
  NS_ASSERT_OWNINGTHREAD(StreamList);
  MOZ_DIAGNOSTIC_ASSERT(!mStreamControl);
  if (mActivated) {
    mContext->RemoveActivity(*this);
    mManager->RemoveStreamList(*this);
    for (uint32_t i = 0; i < mList.Length(); ++i) {
      mManager->ReleaseBodyId(mList[i].mId);
    }
    mManager->ReleaseCacheId(mCacheId);
  }
}

}  // namespace mozilla::dom::cache

[0.37Quellennavigators]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=141584
#Domains=752002