|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* vim: set ts=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 #include "FileInfo.h" |
|
8 #include "nsThreadUtils.h" |
|
9 #include "mozilla/dom/quota/QuotaManager.h" |
|
10 |
|
11 USING_INDEXEDDB_NAMESPACE |
|
12 |
|
13 namespace { |
|
14 |
|
15 class CleanupFileRunnable MOZ_FINAL : public nsIRunnable |
|
16 { |
|
17 public: |
|
18 NS_DECL_THREADSAFE_ISUPPORTS |
|
19 NS_DECL_NSIRUNNABLE |
|
20 |
|
21 CleanupFileRunnable(FileManager* aFileManager, int64_t aFileId); |
|
22 |
|
23 private: |
|
24 nsRefPtr<FileManager> mFileManager; |
|
25 int64_t mFileId; |
|
26 }; |
|
27 |
|
28 } // anonymous namespace |
|
29 |
|
30 // static |
|
31 FileInfo* |
|
32 FileInfo::Create(FileManager* aFileManager, int64_t aId) |
|
33 { |
|
34 MOZ_ASSERT(aId > 0, "Wrong id!"); |
|
35 |
|
36 if (aId <= INT16_MAX) { |
|
37 return new FileInfo16(aFileManager, aId); |
|
38 } |
|
39 |
|
40 if (aId <= INT32_MAX) { |
|
41 return new FileInfo32(aFileManager, aId); |
|
42 } |
|
43 |
|
44 return new FileInfo64(aFileManager, aId); |
|
45 } |
|
46 |
|
47 void |
|
48 FileInfo::GetReferences(int32_t* aRefCnt, int32_t* aDBRefCnt, |
|
49 int32_t* aSliceRefCnt) |
|
50 { |
|
51 if (IndexedDatabaseManager::IsClosed()) { |
|
52 NS_ERROR("Shouldn't be called after shutdown!"); |
|
53 |
|
54 if (aRefCnt) { |
|
55 *aRefCnt = -1; |
|
56 } |
|
57 |
|
58 if (aDBRefCnt) { |
|
59 *aDBRefCnt = -1; |
|
60 } |
|
61 |
|
62 if (aSliceRefCnt) { |
|
63 *aSliceRefCnt = -1; |
|
64 } |
|
65 |
|
66 return; |
|
67 } |
|
68 |
|
69 MutexAutoLock lock(IndexedDatabaseManager::FileMutex()); |
|
70 |
|
71 if (aRefCnt) { |
|
72 *aRefCnt = mRefCnt; |
|
73 } |
|
74 |
|
75 if (aDBRefCnt) { |
|
76 *aDBRefCnt = mDBRefCnt; |
|
77 } |
|
78 |
|
79 if (aSliceRefCnt) { |
|
80 *aSliceRefCnt = mSliceRefCnt; |
|
81 } |
|
82 } |
|
83 |
|
84 void |
|
85 FileInfo::UpdateReferences(mozilla::ThreadSafeAutoRefCnt& aRefCount, |
|
86 int32_t aDelta, bool aClear) |
|
87 { |
|
88 if (IndexedDatabaseManager::IsClosed()) { |
|
89 NS_ERROR("Shouldn't be called after shutdown!"); |
|
90 return; |
|
91 } |
|
92 |
|
93 bool needsCleanup; |
|
94 { |
|
95 MutexAutoLock lock(IndexedDatabaseManager::FileMutex()); |
|
96 |
|
97 aRefCount = aClear ? 0 : aRefCount + aDelta; |
|
98 |
|
99 if (mRefCnt + mDBRefCnt + mSliceRefCnt > 0) { |
|
100 return; |
|
101 } |
|
102 |
|
103 mFileManager->mFileInfos.Remove(Id()); |
|
104 |
|
105 needsCleanup = !mFileManager->Invalidated(); |
|
106 } |
|
107 |
|
108 if (needsCleanup) { |
|
109 Cleanup(); |
|
110 } |
|
111 |
|
112 delete this; |
|
113 } |
|
114 |
|
115 void |
|
116 FileInfo::Cleanup() |
|
117 { |
|
118 nsRefPtr<CleanupFileRunnable> cleaner = |
|
119 new CleanupFileRunnable(mFileManager, Id()); |
|
120 |
|
121 // IndexedDatabaseManager is main-thread only. |
|
122 if (!NS_IsMainThread()) { |
|
123 NS_DispatchToMainThread(cleaner); |
|
124 return; |
|
125 } |
|
126 |
|
127 cleaner->Run(); |
|
128 } |
|
129 |
|
130 CleanupFileRunnable::CleanupFileRunnable(FileManager* aFileManager, |
|
131 int64_t aFileId) |
|
132 : mFileManager(aFileManager), mFileId(aFileId) |
|
133 { |
|
134 } |
|
135 |
|
136 NS_IMPL_ISUPPORTS(CleanupFileRunnable, |
|
137 nsIRunnable) |
|
138 |
|
139 NS_IMETHODIMP |
|
140 CleanupFileRunnable::Run() |
|
141 { |
|
142 if (mozilla::dom::quota::QuotaManager::IsShuttingDown()) { |
|
143 return NS_OK; |
|
144 } |
|
145 |
|
146 nsRefPtr<IndexedDatabaseManager> mgr = IndexedDatabaseManager::Get(); |
|
147 MOZ_ASSERT(mgr); |
|
148 |
|
149 if (NS_FAILED(mgr->AsyncDeleteFile(mFileManager, mFileId))) { |
|
150 NS_WARNING("Failed to delete file asynchronously!"); |
|
151 } |
|
152 |
|
153 return NS_OK; |
|
154 } |