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

Quelle  Manager.h   Sprache: 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/. */


#ifndef mozilla_dom_cache_Manager_h
#define mozilla_dom_cache_Manager_h

#include "mozilla/RefPtr.h"
#include "mozilla/dom/SafeRefPtr.h"
#include "mozilla/dom/cache/Types.h"
#include "mozilla/dom/quota/Client.h"
#include "mozilla/dom/quota/StringifyUtils.h"
#include "CacheCommon.h"
#include "nsCOMPtr.h"
#include "nsISupportsImpl.h"
#include "nsString.h"
#include "nsTArray.h"

class nsIInputStream;
class nsIThread;

namespace mozilla {

class ErrorResult;

namespace dom {

namespace quota {

class ClientDirectoryLock;

}  // namespace quota

namespace cache {

class CacheOpArgs;
class CacheOpResult;
class CacheRequestResponse;
class Context;
class ManagerId;
struct SavedRequest;
struct SavedResponse;
class StreamList;

// The Manager is class is responsible for performing all of the underlying
// work for a Cache or CacheStorage operation.  The DOM objects and IPC actors
// are basically just plumbing to get the request to the right Manager object
// running in the parent process.
//
// There should be exactly one Manager object for each origin or app using the
// Cache API.  This uniqueness is defined by the ManagerId equality operator.
// The uniqueness is enforced by the Manager GetOrCreate() factory method.
//
// The life cycle of Manager objects is somewhat complex.  While code may
// hold a strong reference to the Manager, it will invalidate itself once it
// believes it has become completely idle.  This is currently determined when
// all of the following conditions occur:
//
//  1) There are no more Manager::Listener objects registered with the Manager
//     by performing a Cache or Storage operation.
//  2) There are no more CacheId references noted via Manager::AddRefCacheId().
//  3) There are no more BodyId references noted via Manager::AddRefBodyId().
//
// In order to keep your Manager alive you should perform an operation to set
// a Listener, call AddRefCacheId(), or call AddRefBodyId().
//
// Even once a Manager becomes invalid, however, it may still continue to
// exist.  This is allowed so that any in-progress Actions can gracefully
// complete.
//
// As an invariant, all Manager objects must cease all IO before shutdown.  This
// is enforced by the Manager::Factory.  If content still holds references to
// Cache DOM objects during shutdown, then all operations will begin rejecting.
class Manager final : public SafeRefCounted<Manager>, public Stringifyable {
  using Client = quota::Client;
  using ClientDirectoryLock = quota::ClientDirectoryLock;

 public:
  // Callback interface implemented by clients of Manager, such as CacheParent
  // and CacheStorageParent.  In general, if you call a Manager method you
  // should expect to receive exactly one On*() callback.  For example, if
  // you call Manager::CacheMatch(), then you should expect to receive
  // OnCacheMatch() back in response.
  //
  // Listener objects are set on a per-operation basis.  So you pass the
  // Listener to a call like Manager::CacheMatch().  Once set in this way,
  // the Manager will continue to reference the Listener until RemoveListener()
  // is called.  This is done to allow the same listener to be used for
  // multiple operations simultaneously without having to maintain an exact
  // count of operations-in-flight.
  //
  // Note, the Manager only holds weak references to Listener objects.
  // Listeners must call Manager::RemoveListener() before they are destroyed
  // to clear these weak references.
  //
  // All public methods should be invoked on the same thread used to create
  // the Manager.
  class Listener {
   public:
    // convenience routines
    void OnOpComplete(ErrorResult&& aRv, const CacheOpResult& aResult);

    void OnOpComplete(ErrorResult&& aRv, const CacheOpResult& aResult,
                      CacheId aOpenedCacheId);

    void OnOpComplete(ErrorResult&& aRv, const CacheOpResult& aResult,
                      const SavedResponse& aSavedResponse,
                      StreamList& aStreamList);

    void OnOpComplete(ErrorResult&& aRv, const CacheOpResult& aResult,
                      const nsTArray<SavedResponse>& aSavedResponseList,
                      StreamList& aStreamList);

    void OnOpComplete(ErrorResult&& aRv, const CacheOpResult& aResult,
                      const nsTArray<SavedRequest>& aSavedRequestList,
                      StreamList& aStreamList);

    struct StreamInfo {
      const nsTArray<SavedResponse>& mSavedResponseList;
      const nsTArray<SavedRequest>& mSavedRequestList;
      StreamList& mStreamList;
    };

    // interface to be implemented
    virtual void OnOpComplete(ErrorResult&& aRv, const CacheOpResult& aResult,
                              CacheId aOpenedCacheId,
                              const Maybe<StreamInfo>& aStreamInfo) {}

   protected:
    ~Listener() = default;
  };

  enum State { Open, Closing };

  static Result<SafeRefPtr<Manager>, nsresult> AcquireCreateIfNonExistent(
      const SafeRefPtr<ManagerId>& aManagerId);

  static void InitiateShutdown();

  static bool IsShutdownAllComplete();

  static nsCString GetShutdownStatus();

  // Cancel actions for given DirectoryLock ids.
  static void Abort(const Client::DirectoryLockIdTable& aDirectoryLockIds);

  // Cancel all actions.
  static void AbortAll();

  // Must be called by Listener objects before they are destroyed.
  void RemoveListener(Listener* aListener);

  // Must be called by Context objects before they are destroyed.
  void RemoveContext(Context& aContext);

  // Marks the Manager "invalid".  Once the Context completes no new operations
  // will be permitted with this Manager.  New actors will get a new Manager.
  void NoteClosing();

  State GetState() const;

  // If an actor represents a long term reference to a cache or body stream,
  // then they must call AddRefCacheId() or AddRefBodyId().  This will
  // cause the Manager to keep the backing data store alive for the given
  // object.  The actor must then call ReleaseCacheId() or ReleaseBodyId()
  // exactly once for every AddRef*() call it made.  Any delayed deletion
  // will then be performed.
  void AddRefCacheId(CacheId aCacheId);
  void ReleaseCacheId(CacheId aCacheId);
  void AddRefBodyId(const nsID& aBodyId);
  void ReleaseBodyId(const nsID& aBodyId);

  const ManagerId& GetManagerId() const;

  Maybe<ClientDirectoryLock&> MaybeDirectoryLockRef() const;

  // Methods to allow a StreamList to register themselves with the Manager.
  // StreamList objects must call RemoveStreamList() before they are destroyed.
  void AddStreamList(StreamList& aStreamList);
  void RemoveStreamList(StreamList& aStreamList);

  void ExecuteCacheOp(Listener* aListener, CacheId aCacheId,
                      const CacheOpArgs& aOpArgs);
  void ExecutePutAll(
      Listener* aListener, CacheId aCacheId,
      const nsTArray<CacheRequestResponse>& aPutList,
      const nsTArray<nsCOMPtr<nsIInputStream>>& aRequestStreamList,
      const nsTArray<nsCOMPtr<nsIInputStream>>& aResponseStreamList);

  void ExecuteStorageOp(Listener* aListener, Namespace aNamespace,
                        const CacheOpArgs& aOpArgs);

  void ExecuteOpenStream(Listener* aListener, InputStreamResolver&& aResolver,
                         const nsID& aBodyId);

  void NoteStreamOpenComplete(const nsID& aBodyId, ErrorResult&& aRv,
                              nsCOMPtr<nsIInputStream>&& aBodyStream);

#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
  void RecordMayNotDeleteCSCP(int32_t aCacheStreamControlParentId);
  void RecordHaveDeletedCSCP(int32_t aCacheStreamControlParentId);
#endif

 private:
  class Factory;
  class BaseAction;
  class DeleteOrphanedCacheAction;

  class CacheMatchAction;
  class CacheMatchAllAction;
  class CachePutAllAction;
  class CacheDeleteAction;
  class CacheKeysAction;

  class StorageMatchAction;
  class StorageHasAction;
  class StorageOpenAction;
  class StorageDeleteAction;
  class StorageKeysAction;

  class OpenStreamAction;

  using ListenerId = uint64_t;

  void Init(Maybe<Manager&> aOldManager);
  void Shutdown();

  void Abort();

  ListenerId SaveListener(Listener* aListener);
  Listener* GetListener(ListenerId aListenerId) const;

  bool SetCacheIdOrphanedIfRefed(CacheId aCacheId);
  bool SetBodyIdOrphanedIfRefed(const nsID& aBodyId);
  void NoteOrphanedBodyIdList(const nsTArray<nsID>& aDeletedBodyIdList);

  void MaybeAllowContextToClose();

  SafeRefPtr<ManagerId> mManagerId;
  nsCOMPtr<nsIThread> mIOThread;

  // Weak reference cleared by RemoveContext() in Context destructor.
  Context* MOZ_NON_OWNING_REF mContext;

  // Weak references cleared by RemoveListener() in Listener destructors.
  struct ListenerEntry {
    ListenerEntry() : mId(UINT64_MAX), mListener(nullptr) {}

    ListenerEntry(ListenerId aId, Listener* aListener)
        : mId(aId), mListener(aListener) {}

    ListenerId mId;
    Listener* mListener;
  };

  class ListenerEntryIdComparator {
   public:
    bool Equals(const ListenerEntry& aA, const ListenerId& aB) const {
      return aA.mId == aB;
    }
  };

  class ListenerEntryListenerComparator {
   public:
    bool Equals(const ListenerEntry& aA, const Listener* aB) const {
      return aA.mListener == aB;
    }
  };

  using ListenerList = nsTArray<ListenerEntry>;
  ListenerList mListeners;
  static ListenerId sNextListenerId;

  // Weak references cleared by RemoveStreamList() in StreamList destructors.
  nsTArray<NotNull<StreamList*>> mStreamLists;

  bool mShuttingDown;
  State mState;

  struct CacheIdRefCounter {
    CacheId mCacheId;
    MozRefCountType mCount;
    bool mOrphaned;
  };
  nsTArray<CacheIdRefCounter> mCacheIdRefs;

  struct BodyIdRefCounter {
    nsID mBodyId;
    MozRefCountType mCount;
    bool mOrphaned;
  };
  nsTArray<BodyIdRefCounter> mBodyIdRefs;

  struct ConstructorGuard {};

  void DoStringify(nsACString& aData) override;

 public:
  Manager(SafeRefPtr<ManagerId> aManagerId, nsIThread* aIOThread,
          const ConstructorGuard&);
  ~Manager();

  NS_DECL_OWNINGTHREAD
  MOZ_DECLARE_REFCOUNTED_TYPENAME(cache::Manager)
};

}  // namespace cache
}  // namespace dom
}  // namespace mozilla

#endif  // mozilla_dom_cache_Manager_h

100%


¤ Dauer der Verarbeitung: 0.16 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 ist noch experimentell.