Wed, 31 Dec 2014 06:55:50 +0100
Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2
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/. */
7 #include "FileInfo.h"
8 #include "nsThreadUtils.h"
9 #include "mozilla/dom/quota/QuotaManager.h"
11 USING_INDEXEDDB_NAMESPACE
13 namespace {
15 class CleanupFileRunnable MOZ_FINAL : public nsIRunnable
16 {
17 public:
18 NS_DECL_THREADSAFE_ISUPPORTS
19 NS_DECL_NSIRUNNABLE
21 CleanupFileRunnable(FileManager* aFileManager, int64_t aFileId);
23 private:
24 nsRefPtr<FileManager> mFileManager;
25 int64_t mFileId;
26 };
28 } // anonymous namespace
30 // static
31 FileInfo*
32 FileInfo::Create(FileManager* aFileManager, int64_t aId)
33 {
34 MOZ_ASSERT(aId > 0, "Wrong id!");
36 if (aId <= INT16_MAX) {
37 return new FileInfo16(aFileManager, aId);
38 }
40 if (aId <= INT32_MAX) {
41 return new FileInfo32(aFileManager, aId);
42 }
44 return new FileInfo64(aFileManager, aId);
45 }
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!");
54 if (aRefCnt) {
55 *aRefCnt = -1;
56 }
58 if (aDBRefCnt) {
59 *aDBRefCnt = -1;
60 }
62 if (aSliceRefCnt) {
63 *aSliceRefCnt = -1;
64 }
66 return;
67 }
69 MutexAutoLock lock(IndexedDatabaseManager::FileMutex());
71 if (aRefCnt) {
72 *aRefCnt = mRefCnt;
73 }
75 if (aDBRefCnt) {
76 *aDBRefCnt = mDBRefCnt;
77 }
79 if (aSliceRefCnt) {
80 *aSliceRefCnt = mSliceRefCnt;
81 }
82 }
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 }
93 bool needsCleanup;
94 {
95 MutexAutoLock lock(IndexedDatabaseManager::FileMutex());
97 aRefCount = aClear ? 0 : aRefCount + aDelta;
99 if (mRefCnt + mDBRefCnt + mSliceRefCnt > 0) {
100 return;
101 }
103 mFileManager->mFileInfos.Remove(Id());
105 needsCleanup = !mFileManager->Invalidated();
106 }
108 if (needsCleanup) {
109 Cleanup();
110 }
112 delete this;
113 }
115 void
116 FileInfo::Cleanup()
117 {
118 nsRefPtr<CleanupFileRunnable> cleaner =
119 new CleanupFileRunnable(mFileManager, Id());
121 // IndexedDatabaseManager is main-thread only.
122 if (!NS_IsMainThread()) {
123 NS_DispatchToMainThread(cleaner);
124 return;
125 }
127 cleaner->Run();
128 }
130 CleanupFileRunnable::CleanupFileRunnable(FileManager* aFileManager,
131 int64_t aFileId)
132 : mFileManager(aFileManager), mFileId(aFileId)
133 {
134 }
136 NS_IMPL_ISUPPORTS(CleanupFileRunnable,
137 nsIRunnable)
139 NS_IMETHODIMP
140 CleanupFileRunnable::Run()
141 {
142 if (mozilla::dom::quota::QuotaManager::IsShuttingDown()) {
143 return NS_OK;
144 }
146 nsRefPtr<IndexedDatabaseManager> mgr = IndexedDatabaseManager::Get();
147 MOZ_ASSERT(mgr);
149 if (NS_FAILED(mgr->AsyncDeleteFile(mFileManager, mFileId))) {
150 NS_WARNING("Failed to delete file asynchronously!");
151 }
153 return NS_OK;
154 }