Manager.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #ifndef mozilla_dom_cache_Manager_h
  6. #define mozilla_dom_cache_Manager_h
  7. #include "mozilla/dom/cache/Types.h"
  8. #include "nsCOMPtr.h"
  9. #include "nsISupportsImpl.h"
  10. #include "mozilla/RefPtr.h"
  11. #include "nsString.h"
  12. #include "nsTArray.h"
  13. class nsIInputStream;
  14. class nsIThread;
  15. namespace mozilla {
  16. class ErrorResult;
  17. namespace dom {
  18. namespace cache {
  19. class CacheOpArgs;
  20. class CacheOpResult;
  21. class CacheRequestResponse;
  22. class Context;
  23. class ManagerId;
  24. struct SavedRequest;
  25. struct SavedResponse;
  26. class StreamList;
  27. // The Manager is class is responsible for performing all of the underlying
  28. // work for a Cache or CacheStorage operation. The DOM objects and IPC actors
  29. // are basically just plumbing to get the request to the right Manager object
  30. // running in the parent process.
  31. //
  32. // There should be exactly one Manager object for each origin or app using the
  33. // Cache API. This uniqueness is defined by the ManagerId equality operator.
  34. // The uniqueness is enforced by the Manager GetOrCreate() factory method.
  35. //
  36. // The life cycle of Manager objects is somewhat complex. While code may
  37. // hold a strong reference to the Manager, it will invalidate itself once it
  38. // believes it has become completely idle. This is currently determined when
  39. // all of the following conditions occur:
  40. //
  41. // 1) There are no more Manager::Listener objects registered with the Manager
  42. // by performing a Cache or Storage operation.
  43. // 2) There are no more CacheId references noted via Manager::AddRefCacheId().
  44. // 3) There are no more BodyId references noted via Manager::AddRefBodyId().
  45. //
  46. // In order to keep your Manager alive you should perform an operation to set
  47. // a Listener, call AddRefCacheId(), or call AddRefBodyId().
  48. //
  49. // Even once a Manager becomes invalid, however, it may still continue to
  50. // exist. This is allowed so that any in-progress Actions can gracefully
  51. // complete.
  52. //
  53. // As an invariant, all Manager objects must cease all IO before shutdown. This
  54. // is enforced by the Manager::Factory. If content still holds references to
  55. // Cache DOM objects during shutdown, then all operations will begin rejecting.
  56. class Manager final
  57. {
  58. public:
  59. // Callback interface implemented by clients of Manager, such as CacheParent
  60. // and CacheStorageParent. In general, if you call a Manager method you
  61. // should expect to receive exactly one On*() callback. For example, if
  62. // you call Manager::CacheMatch(), then you should expect to receive
  63. // OnCacheMatch() back in response.
  64. //
  65. // Listener objects are set on a per-operation basis. So you pass the
  66. // Listener to a call like Manager::CacheMatch(). Once set in this way,
  67. // the Manager will continue to reference the Listener until RemoveListener()
  68. // is called. This is done to allow the same listener to be used for
  69. // multiple operations simultaneously without having to maintain an exact
  70. // count of operations-in-flight.
  71. //
  72. // Note, the Manager only holds weak references to Listener objects.
  73. // Listeners must call Manager::RemoveListener() before they are destroyed
  74. // to clear these weak references.
  75. //
  76. // All public methods should be invoked on the same thread used to create
  77. // the Manager.
  78. class Listener
  79. {
  80. public:
  81. // convenience routines
  82. void
  83. OnOpComplete(ErrorResult&& aRv, const CacheOpResult& aResult);
  84. void
  85. OnOpComplete(ErrorResult&& aRv, const CacheOpResult& aResult,
  86. CacheId aOpenedCacheId);
  87. void
  88. OnOpComplete(ErrorResult&& aRv, const CacheOpResult& aResult,
  89. const SavedResponse& aSavedResponse,
  90. StreamList* aStreamList);
  91. void
  92. OnOpComplete(ErrorResult&& aRv, const CacheOpResult& aResult,
  93. const nsTArray<SavedResponse>& aSavedResponseList,
  94. StreamList* aStreamList);
  95. void
  96. OnOpComplete(ErrorResult&& aRv, const CacheOpResult& aResult,
  97. const nsTArray<SavedRequest>& aSavedRequestList,
  98. StreamList* aStreamList);
  99. // interface to be implemented
  100. virtual void
  101. OnOpComplete(ErrorResult&& aRv, const CacheOpResult& aResult,
  102. CacheId aOpenedCacheId,
  103. const nsTArray<SavedResponse>& aSavedResponseList,
  104. const nsTArray<SavedRequest>& aSavedRequestList,
  105. StreamList* aStreamList) { }
  106. protected:
  107. ~Listener() { }
  108. };
  109. enum State
  110. {
  111. Open,
  112. Closing
  113. };
  114. static nsresult GetOrCreate(ManagerId* aManagerId, Manager** aManagerOut);
  115. static already_AddRefed<Manager> Get(ManagerId* aManagerId);
  116. // Synchronously shutdown. This spins the event loop.
  117. static void ShutdownAll();
  118. // Cancel actions for given origin or all actions if passed string is null.
  119. static void Abort(const nsACString& aOrigin);
  120. // Must be called by Listener objects before they are destroyed.
  121. void RemoveListener(Listener* aListener);
  122. // Must be called by Context objects before they are destroyed.
  123. void RemoveContext(Context* aContext);
  124. // Marks the Manager "invalid". Once the Context completes no new operations
  125. // will be permitted with this Manager. New actors will get a new Manager.
  126. void NoteClosing();
  127. State GetState() const;
  128. // If an actor represents a long term reference to a cache or body stream,
  129. // then they must call AddRefCacheId() or AddRefBodyId(). This will
  130. // cause the Manager to keep the backing data store alive for the given
  131. // object. The actor must then call ReleaseCacheId() or ReleaseBodyId()
  132. // exactly once for every AddRef*() call it made. Any delayed deletion
  133. // will then be performed.
  134. void AddRefCacheId(CacheId aCacheId);
  135. void ReleaseCacheId(CacheId aCacheId);
  136. void AddRefBodyId(const nsID& aBodyId);
  137. void ReleaseBodyId(const nsID& aBodyId);
  138. already_AddRefed<ManagerId> GetManagerId() const;
  139. // Methods to allow a StreamList to register themselves with the Manager.
  140. // StreamList objects must call RemoveStreamList() before they are destroyed.
  141. void AddStreamList(StreamList* aStreamList);
  142. void RemoveStreamList(StreamList* aStreamList);
  143. void ExecuteCacheOp(Listener* aListener, CacheId aCacheId,
  144. const CacheOpArgs& aOpArgs);
  145. void ExecutePutAll(Listener* aListener, CacheId aCacheId,
  146. const nsTArray<CacheRequestResponse>& aPutList,
  147. const nsTArray<nsCOMPtr<nsIInputStream>>& aRequestStreamList,
  148. const nsTArray<nsCOMPtr<nsIInputStream>>& aResponseStreamList);
  149. void ExecuteStorageOp(Listener* aListener, Namespace aNamespace,
  150. const CacheOpArgs& aOpArgs);
  151. private:
  152. class Factory;
  153. class BaseAction;
  154. class DeleteOrphanedCacheAction;
  155. class CacheMatchAction;
  156. class CacheMatchAllAction;
  157. class CachePutAllAction;
  158. class CacheDeleteAction;
  159. class CacheKeysAction;
  160. class StorageMatchAction;
  161. class StorageHasAction;
  162. class StorageOpenAction;
  163. class StorageDeleteAction;
  164. class StorageKeysAction;
  165. typedef uint64_t ListenerId;
  166. Manager(ManagerId* aManagerId, nsIThread* aIOThread);
  167. ~Manager();
  168. void Init(Manager* aOldManager);
  169. void Shutdown();
  170. void Abort();
  171. ListenerId SaveListener(Listener* aListener);
  172. Listener* GetListener(ListenerId aListenerId) const;
  173. bool SetCacheIdOrphanedIfRefed(CacheId aCacheId);
  174. bool SetBodyIdOrphanedIfRefed(const nsID& aBodyId);
  175. void NoteOrphanedBodyIdList(const nsTArray<nsID>& aDeletedBodyIdList);
  176. void MaybeAllowContextToClose();
  177. RefPtr<ManagerId> mManagerId;
  178. nsCOMPtr<nsIThread> mIOThread;
  179. // Weak reference cleared by RemoveContext() in Context destructor.
  180. Context* MOZ_NON_OWNING_REF mContext;
  181. // Weak references cleared by RemoveListener() in Listener destructors.
  182. struct ListenerEntry
  183. {
  184. ListenerEntry()
  185. : mId(UINT64_MAX)
  186. , mListener(nullptr)
  187. {
  188. }
  189. ListenerEntry(ListenerId aId, Listener* aListener)
  190. : mId(aId)
  191. , mListener(aListener)
  192. {
  193. }
  194. ListenerId mId;
  195. Listener* mListener;
  196. };
  197. class ListenerEntryIdComparator
  198. {
  199. public:
  200. bool Equals(const ListenerEntry& aA, const ListenerId& aB) const
  201. {
  202. return aA.mId == aB;
  203. }
  204. };
  205. class ListenerEntryListenerComparator
  206. {
  207. public:
  208. bool Equals(const ListenerEntry& aA, const Listener* aB) const
  209. {
  210. return aA.mListener == aB;
  211. }
  212. };
  213. typedef nsTArray<ListenerEntry> ListenerList;
  214. ListenerList mListeners;
  215. static ListenerId sNextListenerId;
  216. // Weak references cleared by RemoveStreamList() in StreamList destructors.
  217. nsTArray<StreamList*> mStreamLists;
  218. bool mShuttingDown;
  219. State mState;
  220. struct CacheIdRefCounter
  221. {
  222. CacheId mCacheId;
  223. MozRefCountType mCount;
  224. bool mOrphaned;
  225. };
  226. nsTArray<CacheIdRefCounter> mCacheIdRefs;
  227. struct BodyIdRefCounter
  228. {
  229. nsID mBodyId;
  230. MozRefCountType mCount;
  231. bool mOrphaned;
  232. };
  233. nsTArray<BodyIdRefCounter> mBodyIdRefs;
  234. public:
  235. NS_INLINE_DECL_REFCOUNTING(cache::Manager)
  236. };
  237. } // namespace cache
  238. } // namespace dom
  239. } // namespace mozilla
  240. #endif // mozilla_dom_cache_Manager_h