Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
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 mozilla_dom_StorageIPC_h
8 : #define mozilla_dom_StorageIPC_h
9 :
10 : #include "mozilla/dom/PStorageChild.h"
11 : #include "mozilla/dom/PStorageParent.h"
12 : #include "StorageDBThread.h"
13 : #include "LocalStorageCache.h"
14 : #include "StorageObserver.h"
15 : #include "mozilla/Mutex.h"
16 : #include "nsAutoPtr.h"
17 :
18 : namespace mozilla {
19 :
20 : class OriginAttributesPattern;
21 :
22 : namespace dom {
23 :
24 : class LocalStorageManager;
25 :
26 : // Child side of the IPC protocol, exposes as DB interface but
27 : // is responsible to send all requests to the parent process
28 : // and expects asynchronous answers. Those are then transparently
29 : // forwarded back to consumers on the child process.
30 : class StorageDBChild final : public StorageDBBridge
31 : , public PStorageChild
32 : {
33 : virtual ~StorageDBChild();
34 :
35 : public:
36 : explicit StorageDBChild(LocalStorageManager* aManager);
37 :
38 : NS_IMETHOD_(MozExternalRefCountType) AddRef(void);
39 : NS_IMETHOD_(MozExternalRefCountType) Release(void);
40 :
41 : void AddIPDLReference();
42 : void ReleaseIPDLReference();
43 :
44 : virtual nsresult Init();
45 : virtual nsresult Shutdown();
46 :
47 : virtual void AsyncPreload(LocalStorageCacheBridge* aCache,
48 : bool aPriority = false);
49 : virtual void AsyncGetUsage(StorageUsageBridge* aUsage);
50 :
51 : virtual void SyncPreload(LocalStorageCacheBridge* aCache,
52 : bool aForceSync = false);
53 :
54 : virtual nsresult AsyncAddItem(LocalStorageCacheBridge* aCache,
55 : const nsAString& aKey, const nsAString& aValue);
56 : virtual nsresult AsyncUpdateItem(LocalStorageCacheBridge* aCache,
57 : const nsAString& aKey,
58 : const nsAString& aValue);
59 : virtual nsresult AsyncRemoveItem(LocalStorageCacheBridge* aCache,
60 : const nsAString& aKey);
61 : virtual nsresult AsyncClear(LocalStorageCacheBridge* aCache);
62 :
63 0 : virtual void AsyncClearAll()
64 : {
65 0 : if (mOriginsHavingData) {
66 0 : mOriginsHavingData->Clear(); /* NO-OP on the child process otherwise */
67 : }
68 0 : }
69 :
70 0 : virtual void AsyncClearMatchingOrigin(const nsACString& aOriginNoSuffix)
71 0 : { /* NO-OP on the child process */ }
72 :
73 0 : virtual void AsyncClearMatchingOriginAttributes(const OriginAttributesPattern& aPattern)
74 0 : { /* NO-OP on the child process */ }
75 :
76 0 : virtual void AsyncFlush()
77 0 : { SendAsyncFlush(); }
78 :
79 : virtual bool ShouldPreloadOrigin(const nsACString& aOriginNoSuffix);
80 0 : virtual void GetOriginsHavingData(InfallibleTArray<nsCString>* aOrigins)
81 0 : { NS_NOTREACHED("Not implemented for child process"); }
82 :
83 : private:
84 : mozilla::ipc::IPCResult RecvObserve(const nsCString& aTopic,
85 : const nsString& aOriginAttributesPattern,
86 : const nsCString& aOriginScope);
87 : mozilla::ipc::IPCResult RecvLoadItem(const nsCString& aOriginSuffix,
88 : const nsCString& aOriginNoSuffix,
89 : const nsString& aKey,
90 : const nsString& aValue);
91 : mozilla::ipc::IPCResult RecvLoadDone(const nsCString& aOriginSuffix,
92 : const nsCString& aOriginNoSuffix,
93 : const nsresult& aRv);
94 : mozilla::ipc::IPCResult RecvOriginsHavingData(nsTArray<nsCString>&& aOrigins);
95 : mozilla::ipc::IPCResult RecvLoadUsage(const nsCString& aOriginNoSuffix,
96 : const int64_t& aUsage);
97 : mozilla::ipc::IPCResult RecvError(const nsresult& aRv);
98 :
99 : nsTHashtable<nsCStringHashKey>& OriginsHavingData();
100 :
101 : ThreadSafeAutoRefCnt mRefCnt;
102 : NS_DECL_OWNINGTHREAD
103 :
104 : // Held to get caches to forward answers to.
105 : RefPtr<LocalStorageManager> mManager;
106 :
107 : // Origins having data hash, for optimization purposes only
108 : nsAutoPtr<nsTHashtable<nsCStringHashKey>> mOriginsHavingData;
109 :
110 : // List of caches waiting for preload. This ensures the contract that
111 : // AsyncPreload call references the cache for time of the preload.
112 : nsTHashtable<nsRefPtrHashKey<LocalStorageCacheBridge>> mLoadingCaches;
113 :
114 : // Status of the remote database
115 : nsresult mStatus;
116 :
117 : bool mIPCOpen;
118 : };
119 :
120 :
121 : // Receives async requests from child processes and is responsible
122 : // to send back responses from the DB thread. Exposes as a fake
123 : // LocalStorageCache consumer.
124 : // Also responsible for forwardning all chrome operation notifications
125 : // such as cookie cleaning etc to the child process.
126 : class StorageDBParent final : public PStorageParent
127 : , public StorageObserverSink
128 : {
129 : virtual ~StorageDBParent();
130 :
131 : public:
132 : StorageDBParent();
133 :
134 : NS_IMETHOD_(MozExternalRefCountType) AddRef(void);
135 : NS_IMETHOD_(MozExternalRefCountType) Release(void);
136 :
137 : void AddIPDLReference();
138 : void ReleaseIPDLReference();
139 :
140 4 : bool IPCOpen() { return mIPCOpen; }
141 :
142 : public:
143 : // Fake cache class receiving async callbacks from DB thread, sending
144 : // them back to appropriate cache object on the child process.
145 : class CacheParentBridge : public LocalStorageCacheBridge {
146 : public:
147 2 : CacheParentBridge(StorageDBParent* aParentDB,
148 : const nsACString& aOriginSuffix,
149 : const nsACString& aOriginNoSuffix)
150 2 : : mParent(aParentDB)
151 : , mOriginSuffix(aOriginSuffix), mOriginNoSuffix(aOriginNoSuffix)
152 2 : , mLoaded(false), mLoadedCount(0) {}
153 6 : virtual ~CacheParentBridge() {}
154 :
155 : // LocalStorageCacheBridge
156 : virtual const nsCString Origin() const;
157 6 : virtual const nsCString& OriginNoSuffix() const
158 6 : { return mOriginNoSuffix; }
159 6 : virtual const nsCString& OriginSuffix() const
160 6 : { return mOriginSuffix; }
161 2 : virtual bool Loaded()
162 2 : { return mLoaded; }
163 2 : virtual uint32_t LoadedCount()
164 2 : { return mLoadedCount; }
165 :
166 : virtual bool LoadItem(const nsAString& aKey, const nsString& aValue);
167 : virtual void LoadDone(nsresult aRv);
168 : virtual void LoadWait();
169 :
170 : private:
171 : RefPtr<StorageDBParent> mParent;
172 : nsCString mOriginSuffix, mOriginNoSuffix;
173 : bool mLoaded;
174 : uint32_t mLoadedCount;
175 : };
176 :
177 : // Fake usage class receiving async callbacks from DB thread
178 : class UsageParentBridge : public StorageUsageBridge
179 : {
180 : public:
181 1 : UsageParentBridge(StorageDBParent* aParentDB,
182 : const nsACString& aOriginScope)
183 1 : : mParent(aParentDB), mOriginScope(aOriginScope) {}
184 3 : virtual ~UsageParentBridge() {}
185 :
186 : // StorageUsageBridge
187 1 : virtual const nsCString& OriginScope() { return mOriginScope; }
188 : virtual void LoadUsage(const int64_t usage);
189 :
190 : private:
191 : RefPtr<StorageDBParent> mParent;
192 : nsCString mOriginScope;
193 : };
194 :
195 : private:
196 : // IPC
197 : virtual void ActorDestroy(ActorDestroyReason aWhy) override;
198 : mozilla::ipc::IPCResult RecvAsyncPreload(const nsCString& aOriginSuffix,
199 : const nsCString& aOriginNoSuffix,
200 : const bool& aPriority) override;
201 : mozilla::ipc::IPCResult RecvPreload(const nsCString& aOriginSuffix,
202 : const nsCString& aOriginNoSuffix,
203 : const uint32_t& aAlreadyLoadedCount,
204 : InfallibleTArray<nsString>* aKeys,
205 : InfallibleTArray<nsString>* aValues,
206 : nsresult* aRv) override;
207 : mozilla::ipc::IPCResult RecvAsyncGetUsage(const nsCString& aOriginNoSuffix) override;
208 : mozilla::ipc::IPCResult RecvAsyncAddItem(const nsCString& aOriginSuffix,
209 : const nsCString& aOriginNoSuffix,
210 : const nsString& aKey,
211 : const nsString& aValue) override;
212 : mozilla::ipc::IPCResult RecvAsyncUpdateItem(const nsCString& aOriginSuffix,
213 : const nsCString& aOriginNoSuffix,
214 : const nsString& aKey,
215 : const nsString& aValue) override;
216 : mozilla::ipc::IPCResult RecvAsyncRemoveItem(const nsCString& aOriginSuffix,
217 : const nsCString& aOriginNoSuffix,
218 : const nsString& aKey) override;
219 : mozilla::ipc::IPCResult RecvAsyncClear(const nsCString& aOriginSuffix,
220 : const nsCString& aOriginNoSuffix) override;
221 : mozilla::ipc::IPCResult RecvAsyncFlush() override;
222 :
223 : // StorageObserverSink
224 : virtual nsresult Observe(const char* aTopic,
225 : const nsAString& aOriginAttrPattern,
226 : const nsACString& aOriginScope) override;
227 :
228 : private:
229 : CacheParentBridge* NewCache(const nsACString& aOriginSuffix,
230 : const nsACString& aOriginNoSuffix);
231 :
232 : ThreadSafeAutoRefCnt mRefCnt;
233 : NS_DECL_OWNINGTHREAD
234 :
235 : // True when IPC channel is open and Send*() methods are OK to use.
236 : bool mIPCOpen;
237 : };
238 :
239 : } // namespace dom
240 : } // namespace mozilla
241 :
242 : #endif // mozilla_dom_StorageIPC_h
|