Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/indexedDB/FileInfo.cpp
Line
Count
Source (jump to first uncovered line)
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
#include "FileInfo.h"
8
9
#include "FileManager.h"
10
#include "IndexedDatabaseManager.h"
11
#include "mozilla/Assertions.h"
12
#include "mozilla/Attributes.h"
13
#include "mozilla/Mutex.h"
14
#include "mozilla/dom/quota/QuotaManager.h"
15
#include "nsError.h"
16
#include "nsThreadUtils.h"
17
18
namespace mozilla {
19
namespace dom {
20
namespace indexedDB {
21
22
using namespace mozilla::dom::quota;
23
24
namespace {
25
26
template <typename IdType>
27
class FileInfoImpl final
28
  : public FileInfo
29
{
30
  IdType mFileId;
31
32
public:
33
  FileInfoImpl(FileManager* aFileManager, IdType aFileId)
34
    : FileInfo(aFileManager)
35
    , mFileId(aFileId)
36
0
  {
37
0
    MOZ_ASSERT(aFileManager);
38
0
    MOZ_ASSERT(aFileId > 0);
39
0
  }
Unexecuted instantiation: Unified_cpp_dom_indexedDB0.cpp:mozilla::dom::indexedDB::(anonymous namespace)::FileInfoImpl<short>::FileInfoImpl(mozilla::dom::indexedDB::FileManager*, short)
Unexecuted instantiation: Unified_cpp_dom_indexedDB0.cpp:mozilla::dom::indexedDB::(anonymous namespace)::FileInfoImpl<int>::FileInfoImpl(mozilla::dom::indexedDB::FileManager*, int)
Unexecuted instantiation: Unified_cpp_dom_indexedDB0.cpp:mozilla::dom::indexedDB::(anonymous namespace)::FileInfoImpl<long>::FileInfoImpl(mozilla::dom::indexedDB::FileManager*, long)
40
41
private:
42
  ~FileInfoImpl()
43
  { }
44
45
  virtual int64_t
46
  Id() const override
47
0
  {
48
0
    return int64_t(mFileId);
49
0
  }
Unexecuted instantiation: Unified_cpp_dom_indexedDB0.cpp:mozilla::dom::indexedDB::(anonymous namespace)::FileInfoImpl<short>::Id() const
Unexecuted instantiation: Unified_cpp_dom_indexedDB0.cpp:mozilla::dom::indexedDB::(anonymous namespace)::FileInfoImpl<int>::Id() const
Unexecuted instantiation: Unified_cpp_dom_indexedDB0.cpp:mozilla::dom::indexedDB::(anonymous namespace)::FileInfoImpl<long>::Id() const
50
};
51
52
class CleanupFileRunnable final
53
  : public Runnable
54
{
55
  RefPtr<FileManager> mFileManager;
56
  int64_t mFileId;
57
58
public:
59
  static void
60
  DoCleanup(FileManager* aFileManager, int64_t aFileId);
61
62
  CleanupFileRunnable(FileManager* aFileManager, int64_t aFileId)
63
    : Runnable("dom::indexedDB::CleanupFileRunnable")
64
    , mFileManager(aFileManager)
65
    , mFileId(aFileId)
66
0
  {
67
0
    MOZ_ASSERT(aFileManager);
68
0
    MOZ_ASSERT(aFileId > 0);
69
0
  }
70
71
  NS_INLINE_DECL_REFCOUNTING_INHERITED(CleanupFileRunnable, Runnable);
72
73
private:
74
  ~CleanupFileRunnable()
75
0
  { }
76
77
  NS_DECL_NSIRUNNABLE
78
};
79
80
} // namespace
81
82
FileInfo::FileInfo(FileManager* aFileManager)
83
  : mFileManager(aFileManager)
84
0
{
85
0
  MOZ_ASSERT(aFileManager);
86
0
}
87
88
FileInfo::~FileInfo()
89
0
{
90
0
}
91
92
// static
93
FileInfo*
94
FileInfo::Create(FileManager* aFileManager, int64_t aId)
95
0
{
96
0
  MOZ_ASSERT(aFileManager);
97
0
  MOZ_ASSERT(aId > 0);
98
0
99
0
  if (aId <= INT16_MAX) {
100
0
    return new FileInfoImpl<int16_t>(aFileManager, aId);
101
0
  }
102
0
103
0
  if (aId <= INT32_MAX) {
104
0
    return new FileInfoImpl<int32_t>(aFileManager, aId);
105
0
  }
106
0
107
0
  return new FileInfoImpl<int64_t>(aFileManager, aId);
108
0
}
109
110
void
111
FileInfo::GetReferences(int32_t* aRefCnt,
112
                        int32_t* aDBRefCnt,
113
                        int32_t* aSliceRefCnt)
114
0
{
115
0
  MOZ_ASSERT(!IndexedDatabaseManager::IsClosed());
116
0
117
0
  MutexAutoLock lock(IndexedDatabaseManager::FileMutex());
118
0
119
0
  if (aRefCnt) {
120
0
    *aRefCnt = mRefCnt;
121
0
  }
122
0
123
0
  if (aDBRefCnt) {
124
0
    *aDBRefCnt = mDBRefCnt;
125
0
  }
126
0
127
0
  if (aSliceRefCnt) {
128
0
    *aSliceRefCnt = mSliceRefCnt;
129
0
  }
130
0
}
131
132
void
133
FileInfo::UpdateReferences(ThreadSafeAutoRefCnt& aRefCount,
134
                           int32_t aDelta,
135
                           CustomCleanupCallback* aCustomCleanupCallback)
136
0
{
137
0
  // XXX This can go away once DOM objects no longer hold FileInfo objects...
138
0
  //     Looking at you, BlobImplBase...
139
0
  //     BlobImplBase is being addressed in bug 1068975.
140
0
  if (IndexedDatabaseManager::IsClosed()) {
141
0
    MOZ_ASSERT(&aRefCount == &mRefCnt);
142
0
    MOZ_ASSERT(aDelta == 1 || aDelta == -1);
143
0
144
0
    if (aDelta > 0) {
145
0
      ++aRefCount;
146
0
    } else {
147
0
      nsrefcnt count = --aRefCount;
148
0
      if (!count) {
149
0
        mRefCnt = 1;
150
0
        delete this;
151
0
      }
152
0
    }
153
0
    return;
154
0
  }
155
0
156
0
  MOZ_ASSERT(!IndexedDatabaseManager::IsClosed());
157
0
158
0
  bool needsCleanup;
159
0
  {
160
0
    MutexAutoLock lock(IndexedDatabaseManager::FileMutex());
161
0
162
0
    aRefCount = aRefCount + aDelta;
163
0
164
0
    if (mRefCnt + mDBRefCnt + mSliceRefCnt > 0) {
165
0
      return;
166
0
    }
167
0
168
0
    mFileManager->mFileInfos.Remove(Id());
169
0
170
0
    needsCleanup = !mFileManager->Invalidated();
171
0
  }
172
0
173
0
  if (needsCleanup) {
174
0
    if (aCustomCleanupCallback) {
175
0
      nsresult rv = aCustomCleanupCallback->Cleanup(mFileManager, Id());
176
0
      if (NS_FAILED(rv)) {
177
0
        NS_WARNING("Custom cleanup failed!");
178
0
      }
179
0
    } else {
180
0
      Cleanup();
181
0
    }
182
0
  }
183
0
184
0
  delete this;
185
0
}
186
187
bool
188
FileInfo::LockedClearDBRefs()
189
0
{
190
0
  MOZ_ASSERT(!IndexedDatabaseManager::IsClosed());
191
0
192
0
  IndexedDatabaseManager::FileMutex().AssertCurrentThreadOwns();
193
0
194
0
  mDBRefCnt = 0;
195
0
196
0
  if (mRefCnt || mSliceRefCnt) {
197
0
    return true;
198
0
  }
199
0
200
0
  // In this case, we are not responsible for removing the file info from the
201
0
  // hashtable. It's up to FileManager which is the only caller of this method.
202
0
203
0
  MOZ_ASSERT(mFileManager->Invalidated());
204
0
205
0
  delete this;
206
0
207
0
  return false;
208
0
}
209
210
void
211
FileInfo::Cleanup()
212
0
{
213
0
  int64_t id = Id();
214
0
215
0
  // IndexedDatabaseManager is main-thread only.
216
0
  if (!NS_IsMainThread()) {
217
0
    RefPtr<CleanupFileRunnable> cleaner =
218
0
      new CleanupFileRunnable(mFileManager, id);
219
0
220
0
    MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(cleaner));
221
0
    return;
222
0
  }
223
0
224
0
  CleanupFileRunnable::DoCleanup(mFileManager, id);
225
0
}
226
227
// static
228
void
229
CleanupFileRunnable::DoCleanup(FileManager* aFileManager, int64_t aFileId)
230
0
{
231
0
  MOZ_ASSERT(NS_IsMainThread());
232
0
  MOZ_ASSERT(aFileManager);
233
0
  MOZ_ASSERT(aFileId > 0);
234
0
235
0
  if (NS_WARN_IF(QuotaManager::IsShuttingDown())) {
236
0
    return;
237
0
  }
238
0
239
0
  RefPtr<IndexedDatabaseManager> mgr = IndexedDatabaseManager::Get();
240
0
  MOZ_ASSERT(mgr);
241
0
242
0
  if (NS_FAILED(mgr->AsyncDeleteFile(aFileManager, aFileId))) {
243
0
    NS_WARNING("Failed to delete file asynchronously!");
244
0
  }
245
0
}
246
247
NS_IMETHODIMP
248
CleanupFileRunnable::Run()
249
0
{
250
0
  MOZ_ASSERT(NS_IsMainThread());
251
0
252
0
  DoCleanup(mFileManager, mFileId);
253
0
254
0
  return NS_OK;
255
0
}
256
257
/* static */ already_AddRefed<nsIFile>
258
FileInfo::GetFileForFileInfo(FileInfo* aFileInfo)
259
0
{
260
0
  FileManager* fileManager = aFileInfo->Manager();
261
0
  nsCOMPtr<nsIFile> directory = fileManager->GetDirectory();
262
0
  if (NS_WARN_IF(!directory)) {
263
0
    return nullptr;
264
0
  }
265
0
266
0
  nsCOMPtr<nsIFile> file = FileManager::GetFileForId(directory,
267
0
                                                     aFileInfo->Id());
268
0
  if (NS_WARN_IF(!file)) {
269
0
    return nullptr;
270
0
  }
271
0
272
0
  return file.forget();
273
0
}
274
275
} // namespace indexedDB
276
} // namespace dom
277
} // namespace mozilla