Line data Source code
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 0 : nsCacheRequest( const nsACString & key,
32 : nsICacheListener * listener,
33 : nsCacheAccessMode accessRequested,
34 : bool blockingMode,
35 : nsCacheSession * session)
36 0 : : mKey(key),
37 : mInfo(0),
38 : mListener(listener),
39 : mLock("nsCacheRequest.mLock"),
40 : mCondVar(mLock, "nsCacheRequest.mCondVar"),
41 0 : mProfileDir(session->ProfileDir())
42 : {
43 0 : MOZ_COUNT_CTOR(nsCacheRequest);
44 0 : PR_INIT_CLIST(this);
45 0 : SetAccessRequested(accessRequested);
46 0 : SetStoragePolicy(session->StoragePolicy());
47 0 : if (session->IsStreamBased()) MarkStreamBased();
48 0 : if (session->WillDoomEntriesIfExpired()) MarkDoomEntriesIfExpired();
49 0 : if (session->IsPrivate()) MarkPrivate();
50 0 : if (blockingMode == nsICache::BLOCKING) MarkBlockingMode();
51 0 : MarkWaitingForValidation();
52 0 : NS_IF_ADDREF(mListener);
53 0 : }
54 :
55 0 : ~nsCacheRequest()
56 0 : {
57 0 : MOZ_COUNT_DTOR(nsCacheRequest);
58 0 : NS_ASSERTION(PR_CLIST_IS_EMPTY(this), "request still on a list");
59 :
60 0 : if (mListener)
61 0 : nsCacheService::ReleaseObject_Locked(mListener, mEventTarget);
62 0 : }
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 0 : void SetAccessRequested(nsCacheAccessMode mode)
78 : {
79 0 : NS_ASSERTION(mode <= 0xFF, "too many bits in nsCacheAccessMode");
80 0 : mInfo &= ~eAccessRequestedMask;
81 0 : mInfo |= mode << 24;
82 0 : }
83 :
84 0 : nsCacheAccessMode AccessRequested()
85 : {
86 0 : return (nsCacheAccessMode)((mInfo >> 24) & 0xFF);
87 : }
88 :
89 0 : void MarkStreamBased() { mInfo |= eStreamBasedMask; }
90 0 : bool IsStreamBased() { return (mInfo & eStreamBasedMask) != 0; }
91 :
92 :
93 0 : void MarkDoomEntriesIfExpired() { mInfo |= eDoomEntriesIfExpiredMask; }
94 0 : bool WillDoomEntriesIfExpired() { return (0 != (mInfo & eDoomEntriesIfExpiredMask)); }
95 :
96 0 : void MarkBlockingMode() { mInfo |= eBlockingModeMask; }
97 0 : bool IsBlocking() { return (0 != (mInfo & eBlockingModeMask)); }
98 : bool IsNonBlocking() { return !(mInfo & eBlockingModeMask); }
99 :
100 0 : void SetStoragePolicy(nsCacheStoragePolicy policy)
101 : {
102 0 : NS_ASSERTION(policy <= 0xFF, "too many bits in nsCacheStoragePolicy");
103 0 : mInfo &= ~eStoragePolicyMask; // clear storage policy bits
104 0 : mInfo |= policy; // or in new bits
105 0 : }
106 :
107 0 : nsCacheStoragePolicy StoragePolicy()
108 : {
109 0 : return (nsCacheStoragePolicy)(mInfo & eStoragePolicyMask);
110 : }
111 :
112 0 : void MarkPrivate() { mInfo |= ePrivateMask; }
113 : void MarkPublic() { mInfo &= ~ePrivateMask; }
114 0 : bool IsPrivate() { return (mInfo & ePrivateMask) != 0; }
115 :
116 0 : void MarkWaitingForValidation() { mInfo |= eWaitingForValidationMask; }
117 0 : void DoneWaitingForValidation() { mInfo &= ~eWaitingForValidationMask; }
118 0 : bool WaitingForValidation()
119 : {
120 0 : return (mInfo & eWaitingForValidationMask) != 0;
121 : }
122 :
123 : nsresult
124 0 : WaitForValidation(void)
125 : {
126 0 : if (!WaitingForValidation()) { // flag already cleared
127 0 : MarkWaitingForValidation(); // set up for next time
128 0 : return NS_OK; // early exit;
129 : }
130 : {
131 0 : MutexAutoLock lock(mLock);
132 0 : while (WaitingForValidation()) {
133 0 : mCondVar.Wait();
134 : }
135 0 : MarkWaitingForValidation(); // set up for next time
136 : }
137 0 : return NS_OK;
138 : }
139 :
140 0 : void WakeUp(void) {
141 0 : DoneWaitingForValidation();
142 0 : MutexAutoLock lock(mLock);
143 0 : mCondVar.Notify();
144 0 : }
145 :
146 : /**
147 : * Data members
148 : */
149 : nsCString mKey;
150 : uint32_t mInfo;
151 : nsICacheListener * mListener; // strong ref
152 : nsCOMPtr<nsIEventTarget> mEventTarget;
153 : Mutex mLock;
154 : CondVar mCondVar;
155 : nsCOMPtr<nsIFile> mProfileDir;
156 : };
157 :
158 : #endif // _nsCacheRequest_h_
|