Bug 1861709 replace AudioCallbackDriver::ThreadRunning() assertions that mean to...
[gecko.git] / netwerk / cache2 / CacheEntry.h
blob68369b152a01102b9e00148e18dbbf99ed6531f7
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #ifndef CacheEntry__h__
6 #define CacheEntry__h__
8 #include "nsICacheEntry.h"
9 #include "CacheFile.h"
11 #include "nsIRunnable.h"
12 #include "nsIOutputStream.h"
13 #include "nsICacheEntryOpenCallback.h"
14 #include "nsICacheEntryDoomCallback.h"
15 #include "nsITransportSecurityInfo.h"
17 #include "nsCOMPtr.h"
18 #include "nsRefPtrHashtable.h"
19 #include "nsHashKeys.h"
20 #include "nsString.h"
21 #include "nsCOMArray.h"
22 #include "nsThreadUtils.h"
23 #include "mozilla/Attributes.h"
24 #include "mozilla/Mutex.h"
25 #include "mozilla/TimeStamp.h"
27 static inline uint32_t PRTimeToSeconds(PRTime t_usec) {
28 return uint32_t(t_usec / PR_USEC_PER_SEC);
31 #define NowInSeconds() PRTimeToSeconds(PR_Now())
33 class nsIOutputStream;
34 class nsIURI;
35 class nsIThread;
37 namespace mozilla {
38 namespace net {
40 class CacheStorageService;
41 class CacheStorage;
42 class CacheOutputCloseListener;
43 class CacheEntryHandle;
45 class CacheEntry final : public nsIRunnable, public CacheFileListener {
46 public:
47 NS_DECL_THREADSAFE_ISUPPORTS
48 NS_DECL_NSIRUNNABLE
50 static uint64_t GetNextId();
52 CacheEntry(const nsACString& aStorageID, const nsACString& aURI,
53 const nsACString& aEnhanceID, bool aUseDisk, bool aSkipSizeCheck,
54 bool aPin);
56 void AsyncOpen(nsICacheEntryOpenCallback* aCallback, uint32_t aFlags);
58 CacheEntryHandle* NewHandle();
59 // For a new and recreated entry w/o a callback, we need to wrap it
60 // with a handle to detect writing consumer is gone.
61 CacheEntryHandle* NewWriteHandle();
63 // Forwarded to from CacheEntryHandle : nsICacheEntry
64 nsresult GetKey(nsACString& aKey);
65 nsresult GetCacheEntryId(uint64_t* aCacheEntryId);
66 nsresult GetPersistent(bool* aPersistToDisk);
67 nsresult GetFetchCount(uint32_t* aFetchCount);
68 nsresult GetLastFetched(uint32_t* aLastFetched);
69 nsresult GetLastModified(uint32_t* aLastModified);
70 nsresult GetExpirationTime(uint32_t* aExpirationTime);
71 nsresult SetExpirationTime(uint32_t expirationTime);
72 nsresult GetOnStartTime(uint64_t* aTime);
73 nsresult GetOnStopTime(uint64_t* aTime);
74 nsresult SetNetworkTimes(uint64_t onStartTime, uint64_t onStopTime);
75 nsresult SetContentType(uint8_t aContentType);
76 nsresult ForceValidFor(uint32_t aSecondsToTheFuture);
77 nsresult GetIsForcedValid(bool* aIsForcedValid);
78 nsresult MarkForcedValidUse();
79 nsresult OpenInputStream(int64_t offset, nsIInputStream** _retval);
80 nsresult OpenOutputStream(int64_t offset, int64_t predictedSize,
81 nsIOutputStream** _retval);
82 nsresult GetSecurityInfo(nsITransportSecurityInfo** aSecurityInfo);
83 nsresult SetSecurityInfo(nsITransportSecurityInfo* aSecurityInfo);
84 nsresult GetStorageDataSize(uint32_t* aStorageDataSize);
85 nsresult AsyncDoom(nsICacheEntryDoomCallback* aCallback);
86 nsresult GetMetaDataElement(const char* key, char** aRetval);
87 nsresult SetMetaDataElement(const char* key, const char* value);
88 nsresult VisitMetaData(nsICacheEntryMetaDataVisitor* visitor);
89 nsresult MetaDataReady(void);
90 nsresult SetValid(void);
91 nsresult GetDiskStorageSizeInKB(uint32_t* aDiskStorageSizeInKB);
92 nsresult Recreate(bool aMemoryOnly, nsICacheEntry** _retval);
93 nsresult GetDataSize(int64_t* aDataSize);
94 nsresult GetAltDataSize(int64_t* aDataSize);
95 nsresult GetAltDataType(nsACString& aAltDataType);
96 nsresult OpenAlternativeOutputStream(const nsACString& type,
97 int64_t predictedSize,
98 nsIAsyncOutputStream** _retval);
99 nsresult OpenAlternativeInputStream(const nsACString& type,
100 nsIInputStream** _retval);
101 nsresult GetLoadContextInfo(nsILoadContextInfo** aInfo);
102 nsresult Close(void);
103 nsresult MarkValid(void);
104 nsresult MaybeMarkValid(void);
105 nsresult HasWriteAccess(bool aWriteAllowed, bool* aWriteAccess);
107 public:
108 uint32_t GetMetadataMemoryConsumption();
109 nsCString const& GetStorageID() const { return mStorageID; }
110 nsCString const& GetEnhanceID() const { return mEnhanceID; }
111 nsCString const& GetURI() const { return mURI; }
112 // Accessible at any time
113 bool IsUsingDisk() const { return mUseDisk; }
114 bool IsReferenced() const MOZ_NO_THREAD_SAFETY_ANALYSIS;
115 bool IsFileDoomed();
116 bool IsDoomed() const { return mIsDoomed; }
117 bool IsPinned() const { return mPinned; }
119 // Methods for entry management (eviction from memory),
120 // called only on the management thread.
122 // TODO make these inline
123 double GetFrecency() const;
124 uint32_t GetExpirationTime() const;
125 uint32_t UseCount() const { return mUseCount; }
127 bool IsRegistered() const;
128 bool CanRegister() const;
129 void SetRegistered(bool aRegistered);
131 TimeStamp const& LoadStart() const { return mLoadStart; }
133 enum EPurge {
134 PURGE_DATA_ONLY_DISK_BACKED,
135 PURGE_WHOLE_ONLY_DISK_BACKED,
136 PURGE_WHOLE,
139 bool DeferOrBypassRemovalOnPinStatus(bool aPinned);
140 bool Purge(uint32_t aWhat);
141 void PurgeAndDoom();
142 void DoomAlreadyRemoved();
144 nsresult HashingKeyWithStorage(nsACString& aResult) const;
145 nsresult HashingKey(nsACString& aResult) const;
147 static nsresult HashingKey(const nsACString& aStorageID,
148 const nsACString& aEnhanceID, nsIURI* aURI,
149 nsACString& aResult);
151 static nsresult HashingKey(const nsACString& aStorageID,
152 const nsACString& aEnhanceID,
153 const nsACString& aURISpec, nsACString& aResult);
155 // Accessed only on the service management thread
156 double mFrecency{0};
157 ::mozilla::Atomic<uint32_t, ::mozilla::Relaxed> mSortingExpirationTime{
158 uint32_t(-1)};
160 // Memory reporting
161 size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf);
162 size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf);
164 private:
165 virtual ~CacheEntry();
167 // CacheFileListener
168 NS_IMETHOD OnFileReady(nsresult aResult, bool aIsNew) override;
169 NS_IMETHOD OnFileDoomed(nsresult aResult) override;
171 // Keep the service alive during life-time of an entry
172 RefPtr<CacheStorageService> mService;
174 // We must monitor when a cache entry whose consumer is responsible
175 // for writing it the first time gets released. We must then invoke
176 // waiting callbacks to not break the chain.
177 class Callback {
178 public:
179 Callback(CacheEntry* aEntry, nsICacheEntryOpenCallback* aCallback,
180 bool aReadOnly, bool aCheckOnAnyThread, bool aSecret);
181 // Special constructor for Callback objects added to the chain
182 // just to ensure proper defer dooming (recreation) of this entry.
183 Callback(CacheEntry* aEntry, bool aDoomWhenFoundInPinStatus);
184 Callback(Callback const& aThat);
185 ~Callback();
187 // Called when this callback record changes it's owning entry,
188 // mainly during recreation.
189 void ExchangeEntry(CacheEntry* aEntry) MOZ_REQUIRES(aEntry->mLock);
191 // Returns true when an entry is about to be "defer" doomed and this is
192 // a "defer" callback. The caller must hold a lock (this entry is in the
193 // caller's mCallback array)
194 bool DeferDoom(bool* aDoom) const;
196 // We are raising reference count here to take into account the pending
197 // callback (that virtually holds a ref to this entry before it gets
198 // it's pointer).
199 RefPtr<CacheEntry> mEntry;
200 nsCOMPtr<nsICacheEntryOpenCallback> mCallback;
201 nsCOMPtr<nsIEventTarget> mTarget;
202 bool mReadOnly : 1;
203 bool mRevalidating : 1;
204 bool mCheckOnAnyThread : 1;
205 bool mRecheckAfterWrite : 1;
206 bool mNotWanted : 1;
207 bool mSecret : 1;
209 // These are set only for the defer-doomer Callback instance inserted
210 // to the callback chain. When any of these is set and also any of
211 // the corressponding flags on the entry is set, this callback will
212 // indicate (via DeferDoom()) the entry have to be recreated/doomed.
213 bool mDoomWhenFoundPinned : 1;
214 bool mDoomWhenFoundNonPinned : 1;
216 nsresult OnCheckThread(bool* aOnCheckThread) const;
217 nsresult OnAvailThread(bool* aOnAvailThread) const;
220 // Since OnCacheEntryAvailable must be invoked on the main thread
221 // we need a runnable for it...
222 class AvailableCallbackRunnable : public Runnable {
223 public:
224 AvailableCallbackRunnable(CacheEntry* aEntry, Callback const& aCallback)
225 : Runnable("CacheEntry::AvailableCallbackRunnable"),
226 mEntry(aEntry),
227 mCallback(aCallback) {}
229 private:
230 NS_IMETHOD Run() override {
231 mEntry->InvokeAvailableCallback(mCallback);
232 return NS_OK;
235 RefPtr<CacheEntry> mEntry;
236 Callback mCallback;
239 // Since OnCacheEntryDoomed must be invoked on the main thread
240 // we need a runnable for it...
241 class DoomCallbackRunnable : public Runnable {
242 public:
243 DoomCallbackRunnable(CacheEntry* aEntry, nsresult aRv)
244 : Runnable("net::CacheEntry::DoomCallbackRunnable"),
245 mEntry(aEntry),
246 mRv(aRv) {}
248 private:
249 NS_IMETHOD Run() override {
250 nsCOMPtr<nsICacheEntryDoomCallback> callback;
252 mozilla::MutexAutoLock lock(mEntry->mLock);
253 mEntry->mDoomCallback.swap(callback);
256 if (callback) callback->OnCacheEntryDoomed(mRv);
257 return NS_OK;
260 RefPtr<CacheEntry> mEntry;
261 nsresult mRv;
264 // Starts the load or just invokes the callback, bypasses (when required)
265 // if busy. Returns true on job done, false on bypass.
266 bool Open(Callback& aCallback, bool aTruncate, bool aPriority,
267 bool aBypassIfBusy);
268 // Loads from disk asynchronously
269 bool Load(bool aTruncate, bool aPriority);
271 void RememberCallback(Callback& aCallback) MOZ_REQUIRES(mLock);
272 void InvokeCallbacksLock();
273 void InvokeCallbacks();
274 bool InvokeCallbacks(bool aReadOnly);
275 bool InvokeCallback(Callback& aCallback);
276 void InvokeAvailableCallback(Callback const& aCallback);
277 void OnFetched(Callback const& aCallback);
279 nsresult OpenOutputStreamInternal(int64_t offset, nsIOutputStream** _retval);
280 nsresult OpenInputStreamInternal(int64_t offset, const char* aAltDataType,
281 nsIInputStream** _retval);
283 void OnHandleClosed(CacheEntryHandle const* aHandle);
285 private:
286 friend class CacheEntryHandle;
287 // Increment/decrements the number of handles keeping this entry.
288 void AddHandleRef() MOZ_REQUIRES(mLock) { ++mHandlesCount; }
289 void ReleaseHandleRef() MOZ_REQUIRES(mLock) { --mHandlesCount; }
290 // Current number of handles keeping this entry.
291 uint32_t HandlesCount() const MOZ_REQUIRES(mLock) { return mHandlesCount; }
293 private:
294 friend class CacheOutputCloseListener;
295 void OnOutputClosed();
297 private:
298 // Schedules a background operation on the management thread.
299 // When executed on the management thread directly, the operation(s)
300 // is (are) executed immediately.
301 void BackgroundOp(uint32_t aOperation, bool aForceAsync = false);
302 void StoreFrecency(double aFrecency);
304 // Called only from DoomAlreadyRemoved()
305 void DoomFile() MOZ_REQUIRES(mLock);
306 // When this entry is doomed the first time, this method removes
307 // any force-valid timing info for this entry.
308 void RemoveForcedValidity();
310 already_AddRefed<CacheEntryHandle> ReopenTruncated(
311 bool aMemoryOnly, nsICacheEntryOpenCallback* aCallback);
312 void TransferCallbacks(CacheEntry& aFromEntry);
314 mozilla::Mutex mLock{"CacheEntry"};
316 // Reflects the number of existing handles for this entry
317 ::mozilla::ThreadSafeAutoRefCnt mHandlesCount MOZ_GUARDED_BY(mLock);
319 nsTArray<Callback> mCallbacks MOZ_GUARDED_BY(mLock);
320 nsCOMPtr<nsICacheEntryDoomCallback> mDoomCallback;
322 // Set in CacheEntry::Load(), only - shouldn't need to be under lock
323 // XXX FIX? is this correct?
324 RefPtr<CacheFile> mFile;
326 // Using ReleaseAcquire since we only control access to mFile with this.
327 // When mFileStatus is read and found success it is ensured there is mFile and
328 // that it is after a successful call to Init().
329 Atomic<nsresult, ReleaseAcquire> mFileStatus{NS_ERROR_NOT_INITIALIZED};
330 // Set in constructor
331 nsCString const mURI;
332 nsCString const mEnhanceID;
333 nsCString const mStorageID;
335 // mUseDisk, mSkipSizeCheck, mIsDoomed are plain "bool", not "bool:1",
336 // so as to avoid bitfield races with the byte containing
337 // mSecurityInfoLoaded et al. See bug 1278524.
339 // Whether it's allowed to persist the data to disk
340 bool const mUseDisk;
341 // Whether it should skip max size check.
342 bool const mSkipSizeCheck;
343 // Set when entry is doomed with AsyncDoom() or DoomAlreadyRemoved().
344 Atomic<bool, Relaxed> mIsDoomed{false};
345 // The indication of pinning this entry was open with
346 Atomic<bool, Relaxed> mPinned;
348 // Following flags are all synchronized with the cache entry lock.
350 // Whether security info has already been looked up in metadata.
351 bool mSecurityInfoLoaded : 1 MOZ_GUARDED_BY(mLock);
352 // Prevents any callback invocation
353 bool mPreventCallbacks : 1 MOZ_GUARDED_BY(mLock);
354 // true: after load and an existing file, or after output stream has been
355 // opened.
356 // note - when opening an input stream, and this flag is false, output
357 // stream is open along ; this makes input streams on new entries
358 // behave correctly when EOF is reached (WOULD_BLOCK is returned).
359 // false: after load and a new file, or dropped to back to false when a
360 // writer fails to open an output stream.
361 bool mHasData : 1 MOZ_GUARDED_BY(mLock);
362 // Whether the pinning state of the entry is known (equals to the actual state
363 // of the cache file)
364 bool mPinningKnown : 1 MOZ_GUARDED_BY(mLock);
366 static char const* StateString(uint32_t aState);
368 enum EState { // transiting to:
369 NOTLOADED = 0, // -> LOADING | EMPTY
370 LOADING = 1, // -> EMPTY | READY
371 EMPTY = 2, // -> WRITING
372 WRITING = 3, // -> EMPTY | READY
373 READY = 4, // -> REVALIDATING
374 REVALIDATING = 5 // -> READY
377 // State of this entry.
378 EState mState MOZ_GUARDED_BY(mLock){NOTLOADED};
380 enum ERegistration {
381 NEVERREGISTERED = 0, // The entry has never been registered
382 REGISTERED = 1, // The entry is stored in the memory pool index
383 DEREGISTERED = 2 // The entry has been removed from the pool
386 // Accessed only on the management thread. Records the state of registration
387 // this entry in the memory pool intermediate cache.
388 ERegistration mRegistration{NEVERREGISTERED};
390 // If a new (empty) entry is requested to open an input stream before
391 // output stream has been opened, we must open output stream internally
392 // on CacheFile and hold until writer releases the entry or opens the output
393 // stream for read (then we trade him mOutputStream).
394 nsCOMPtr<nsIOutputStream> mOutputStream MOZ_GUARDED_BY(mLock);
396 // Weak reference to the current writter. There can be more then one
397 // writer at a time and OnHandleClosed() must be processed only for the
398 // current one.
399 CacheEntryHandle* mWriter MOZ_GUARDED_BY(mLock){nullptr};
401 // Background thread scheduled operation. Set (under the lock) one
402 // of this flags to tell the background thread what to do.
403 class Ops {
404 public:
405 static uint32_t const REGISTER = 1 << 0;
406 static uint32_t const FRECENCYUPDATE = 1 << 1;
407 static uint32_t const CALLBACKS = 1 << 2;
408 static uint32_t const UNREGISTER = 1 << 3;
410 Ops() = default;
411 uint32_t Grab() {
412 uint32_t flags = mFlags;
413 mFlags = 0;
414 return flags;
416 bool Set(uint32_t aFlags) {
417 if (mFlags & aFlags) return false;
418 mFlags |= aFlags;
419 return true;
422 private:
423 uint32_t mFlags{0};
424 } mBackgroundOperations;
426 nsCOMPtr<nsITransportSecurityInfo> mSecurityInfo;
427 mozilla::TimeStamp mLoadStart;
428 uint32_t mUseCount{0};
430 const uint64_t mCacheEntryId;
433 class CacheEntryHandle final : public nsICacheEntry {
434 public:
435 explicit CacheEntryHandle(CacheEntry* aEntry);
436 CacheEntry* Entry() const { return mEntry; }
438 NS_DECL_THREADSAFE_ISUPPORTS
440 // Default implementation is simply safely forwarded.
441 NS_IMETHOD GetKey(nsACString& aKey) override { return mEntry->GetKey(aKey); }
442 NS_IMETHOD GetCacheEntryId(uint64_t* aCacheEntryId) override {
443 return mEntry->GetCacheEntryId(aCacheEntryId);
445 NS_IMETHOD GetPersistent(bool* aPersistent) override {
446 return mEntry->GetPersistent(aPersistent);
448 NS_IMETHOD GetFetchCount(uint32_t* aFetchCount) override {
449 return mEntry->GetFetchCount(aFetchCount);
451 NS_IMETHOD GetLastFetched(uint32_t* aLastFetched) override {
452 return mEntry->GetLastFetched(aLastFetched);
454 NS_IMETHOD GetLastModified(uint32_t* aLastModified) override {
455 return mEntry->GetLastModified(aLastModified);
457 NS_IMETHOD GetExpirationTime(uint32_t* aExpirationTime) override {
458 return mEntry->GetExpirationTime(aExpirationTime);
460 NS_IMETHOD SetExpirationTime(uint32_t expirationTime) override {
461 return mEntry->SetExpirationTime(expirationTime);
463 NS_IMETHOD GetOnStartTime(uint64_t* aOnStartTime) override {
464 return mEntry->GetOnStartTime(aOnStartTime);
466 NS_IMETHOD GetOnStopTime(uint64_t* aOnStopTime) override {
467 return mEntry->GetOnStopTime(aOnStopTime);
469 NS_IMETHOD SetNetworkTimes(uint64_t onStartTime,
470 uint64_t onStopTime) override {
471 return mEntry->SetNetworkTimes(onStartTime, onStopTime);
473 NS_IMETHOD SetContentType(uint8_t contentType) override {
474 return mEntry->SetContentType(contentType);
476 NS_IMETHOD ForceValidFor(uint32_t aSecondsToTheFuture) override {
477 return mEntry->ForceValidFor(aSecondsToTheFuture);
479 NS_IMETHOD GetIsForcedValid(bool* aIsForcedValid) override {
480 return mEntry->GetIsForcedValid(aIsForcedValid);
482 NS_IMETHOD MarkForcedValidUse() override {
483 return mEntry->MarkForcedValidUse();
485 NS_IMETHOD OpenInputStream(int64_t offset,
486 nsIInputStream** _retval) override {
487 return mEntry->OpenInputStream(offset, _retval);
489 NS_IMETHOD OpenOutputStream(int64_t offset, int64_t predictedSize,
490 nsIOutputStream** _retval) override {
491 return mEntry->OpenOutputStream(offset, predictedSize, _retval);
493 NS_IMETHOD GetSecurityInfo(
494 nsITransportSecurityInfo** aSecurityInfo) override {
495 return mEntry->GetSecurityInfo(aSecurityInfo);
497 NS_IMETHOD SetSecurityInfo(nsITransportSecurityInfo* aSecurityInfo) override {
498 return mEntry->SetSecurityInfo(aSecurityInfo);
500 NS_IMETHOD GetStorageDataSize(uint32_t* aStorageDataSize) override {
501 return mEntry->GetStorageDataSize(aStorageDataSize);
503 NS_IMETHOD AsyncDoom(nsICacheEntryDoomCallback* listener) override {
504 return mEntry->AsyncDoom(listener);
506 NS_IMETHOD GetMetaDataElement(const char* key, char** _retval) override {
507 return mEntry->GetMetaDataElement(key, _retval);
509 NS_IMETHOD SetMetaDataElement(const char* key, const char* value) override {
510 return mEntry->SetMetaDataElement(key, value);
512 NS_IMETHOD VisitMetaData(nsICacheEntryMetaDataVisitor* visitor) override {
513 return mEntry->VisitMetaData(visitor);
515 NS_IMETHOD MetaDataReady(void) override { return mEntry->MetaDataReady(); }
516 NS_IMETHOD SetValid(void) override { return mEntry->SetValid(); }
517 NS_IMETHOD GetDiskStorageSizeInKB(uint32_t* aDiskStorageSizeInKB) override {
518 return mEntry->GetDiskStorageSizeInKB(aDiskStorageSizeInKB);
520 NS_IMETHOD Recreate(bool aMemoryOnly, nsICacheEntry** _retval) override {
521 return mEntry->Recreate(aMemoryOnly, _retval);
523 NS_IMETHOD GetDataSize(int64_t* aDataSize) override {
524 return mEntry->GetDataSize(aDataSize);
526 NS_IMETHOD GetAltDataSize(int64_t* aAltDataSize) override {
527 return mEntry->GetAltDataSize(aAltDataSize);
529 NS_IMETHOD GetAltDataType(nsACString& aType) override {
530 return mEntry->GetAltDataType(aType);
532 NS_IMETHOD OpenAlternativeOutputStream(
533 const nsACString& type, int64_t predictedSize,
534 nsIAsyncOutputStream** _retval) override {
535 return mEntry->OpenAlternativeOutputStream(type, predictedSize, _retval);
537 NS_IMETHOD OpenAlternativeInputStream(const nsACString& type,
538 nsIInputStream** _retval) override {
539 return mEntry->OpenAlternativeInputStream(type, _retval);
541 NS_IMETHOD GetLoadContextInfo(
542 nsILoadContextInfo** aLoadContextInfo) override {
543 return mEntry->GetLoadContextInfo(aLoadContextInfo);
545 NS_IMETHOD Close(void) override { return mEntry->Close(); }
546 NS_IMETHOD MarkValid(void) override { return mEntry->MarkValid(); }
547 NS_IMETHOD MaybeMarkValid(void) override { return mEntry->MaybeMarkValid(); }
548 NS_IMETHOD HasWriteAccess(bool aWriteAllowed, bool* _retval) override {
549 return mEntry->HasWriteAccess(aWriteAllowed, _retval);
552 // Specific implementation:
553 NS_IMETHOD Dismiss() override;
555 private:
556 virtual ~CacheEntryHandle();
557 RefPtr<CacheEntry> mEntry;
559 // This is |false| until Dismiss() was called and prevents OnHandleClosed
560 // being called more than once.
561 Atomic<bool, ReleaseAcquire> mClosed{false};
564 class CacheOutputCloseListener final : public Runnable {
565 public:
566 void OnOutputClosed();
568 private:
569 friend class CacheEntry;
571 virtual ~CacheOutputCloseListener() = default;
573 NS_DECL_NSIRUNNABLE
574 explicit CacheOutputCloseListener(CacheEntry* aEntry);
576 private:
577 RefPtr<CacheEntry> mEntry;
580 } // namespace net
581 } // namespace mozilla
583 #endif