|
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
|
2 * |
|
3 * This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 #ifndef _nsCacheRequest_h_ |
|
8 #define _nsCacheRequest_h_ |
|
9 |
|
10 #include "nspr.h" |
|
11 #include "mozilla/CondVar.h" |
|
12 #include "mozilla/Mutex.h" |
|
13 #include "nsCOMPtr.h" |
|
14 #include "nsICache.h" |
|
15 #include "nsICacheListener.h" |
|
16 #include "nsCacheSession.h" |
|
17 #include "nsCacheService.h" |
|
18 |
|
19 |
|
20 class nsCacheRequest : public PRCList |
|
21 { |
|
22 typedef mozilla::CondVar CondVar; |
|
23 typedef mozilla::MutexAutoLock MutexAutoLock; |
|
24 typedef mozilla::Mutex Mutex; |
|
25 |
|
26 private: |
|
27 friend class nsCacheService; |
|
28 friend class nsCacheEntry; |
|
29 friend class nsProcessRequestEvent; |
|
30 |
|
31 nsCacheRequest( const nsACString & key, |
|
32 nsICacheListener * listener, |
|
33 nsCacheAccessMode accessRequested, |
|
34 bool blockingMode, |
|
35 nsCacheSession * session) |
|
36 : mKey(key), |
|
37 mInfo(0), |
|
38 mListener(listener), |
|
39 mLock("nsCacheRequest.mLock"), |
|
40 mCondVar(mLock, "nsCacheRequest.mCondVar"), |
|
41 mProfileDir(session->ProfileDir()) |
|
42 { |
|
43 MOZ_COUNT_CTOR(nsCacheRequest); |
|
44 PR_INIT_CLIST(this); |
|
45 SetAccessRequested(accessRequested); |
|
46 SetStoragePolicy(session->StoragePolicy()); |
|
47 if (session->IsStreamBased()) MarkStreamBased(); |
|
48 if (session->WillDoomEntriesIfExpired()) MarkDoomEntriesIfExpired(); |
|
49 if (session->IsPrivate()) MarkPrivate(); |
|
50 if (blockingMode == nsICache::BLOCKING) MarkBlockingMode(); |
|
51 MarkWaitingForValidation(); |
|
52 NS_IF_ADDREF(mListener); |
|
53 } |
|
54 |
|
55 ~nsCacheRequest() |
|
56 { |
|
57 MOZ_COUNT_DTOR(nsCacheRequest); |
|
58 NS_ASSERTION(PR_CLIST_IS_EMPTY(this), "request still on a list"); |
|
59 |
|
60 if (mListener) |
|
61 nsCacheService::ReleaseObject_Locked(mListener, mThread); |
|
62 } |
|
63 |
|
64 /** |
|
65 * Simple Accessors |
|
66 */ |
|
67 enum CacheRequestInfo { |
|
68 eStoragePolicyMask = 0x000000FF, |
|
69 eStreamBasedMask = 0x00000100, |
|
70 ePrivateMask = 0x00000200, |
|
71 eDoomEntriesIfExpiredMask = 0x00001000, |
|
72 eBlockingModeMask = 0x00010000, |
|
73 eWaitingForValidationMask = 0x00100000, |
|
74 eAccessRequestedMask = 0xFF000000 |
|
75 }; |
|
76 |
|
77 void SetAccessRequested(nsCacheAccessMode mode) |
|
78 { |
|
79 NS_ASSERTION(mode <= 0xFF, "too many bits in nsCacheAccessMode"); |
|
80 mInfo &= ~eAccessRequestedMask; |
|
81 mInfo |= mode << 24; |
|
82 } |
|
83 |
|
84 nsCacheAccessMode AccessRequested() |
|
85 { |
|
86 return (nsCacheAccessMode)((mInfo >> 24) & 0xFF); |
|
87 } |
|
88 |
|
89 void MarkStreamBased() { mInfo |= eStreamBasedMask; } |
|
90 bool IsStreamBased() { return (mInfo & eStreamBasedMask) != 0; } |
|
91 |
|
92 |
|
93 void MarkDoomEntriesIfExpired() { mInfo |= eDoomEntriesIfExpiredMask; } |
|
94 bool WillDoomEntriesIfExpired() { return (0 != (mInfo & eDoomEntriesIfExpiredMask)); } |
|
95 |
|
96 void MarkBlockingMode() { mInfo |= eBlockingModeMask; } |
|
97 bool IsBlocking() { return (0 != (mInfo & eBlockingModeMask)); } |
|
98 bool IsNonBlocking() { return !(mInfo & eBlockingModeMask); } |
|
99 |
|
100 void SetStoragePolicy(nsCacheStoragePolicy policy) |
|
101 { |
|
102 NS_ASSERTION(policy <= 0xFF, "too many bits in nsCacheStoragePolicy"); |
|
103 mInfo &= ~eStoragePolicyMask; // clear storage policy bits |
|
104 mInfo |= policy; // or in new bits |
|
105 } |
|
106 |
|
107 nsCacheStoragePolicy StoragePolicy() |
|
108 { |
|
109 return (nsCacheStoragePolicy)(mInfo & eStoragePolicyMask); |
|
110 } |
|
111 |
|
112 void MarkPrivate() { mInfo |= ePrivateMask; } |
|
113 void MarkPublic() { mInfo &= ~ePrivateMask; } |
|
114 bool IsPrivate() { return (mInfo & ePrivateMask) != 0; } |
|
115 |
|
116 void MarkWaitingForValidation() { mInfo |= eWaitingForValidationMask; } |
|
117 void DoneWaitingForValidation() { mInfo &= ~eWaitingForValidationMask; } |
|
118 bool WaitingForValidation() |
|
119 { |
|
120 return (mInfo & eWaitingForValidationMask) != 0; |
|
121 } |
|
122 |
|
123 nsresult |
|
124 WaitForValidation(void) |
|
125 { |
|
126 if (!WaitingForValidation()) { // flag already cleared |
|
127 MarkWaitingForValidation(); // set up for next time |
|
128 return NS_OK; // early exit; |
|
129 } |
|
130 { |
|
131 MutexAutoLock lock(mLock); |
|
132 while (WaitingForValidation()) { |
|
133 mCondVar.Wait(); |
|
134 } |
|
135 MarkWaitingForValidation(); // set up for next time |
|
136 } |
|
137 return NS_OK; |
|
138 } |
|
139 |
|
140 void WakeUp(void) { |
|
141 DoneWaitingForValidation(); |
|
142 MutexAutoLock lock(mLock); |
|
143 mCondVar.Notify(); |
|
144 } |
|
145 |
|
146 /** |
|
147 * Data members |
|
148 */ |
|
149 nsCString mKey; |
|
150 uint32_t mInfo; |
|
151 nsICacheListener * mListener; // strong ref |
|
152 nsCOMPtr<nsIThread> mThread; |
|
153 Mutex mLock; |
|
154 CondVar mCondVar; |
|
155 nsCOMPtr<nsIFile> mProfileDir; |
|
156 }; |
|
157 |
|
158 #endif // _nsCacheRequest_h_ |