Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/indexedDB/IDBMutableFile.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 file,
5
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "IDBMutableFile.h"
8
9
#include "ActorsChild.h"
10
#include "FileInfo.h"
11
#include "IDBDatabase.h"
12
#include "IDBFactory.h"
13
#include "IDBFileHandle.h"
14
#include "IDBFileRequest.h"
15
#include "IndexedDatabaseManager.h"
16
#include "MainThreadUtils.h"
17
#include "mozilla/Assertions.h"
18
#include "mozilla/ErrorResult.h"
19
#include "mozilla/dom/File.h"
20
#include "mozilla/dom/IDBMutableFileBinding.h"
21
#include "mozilla/dom/indexedDB/PBackgroundIDBSharedTypes.h"
22
#include "mozilla/dom/quota/FileStreams.h"
23
#include "mozilla/dom/quota/QuotaManager.h"
24
#include "mozilla/ipc/BackgroundUtils.h"
25
#include "mozilla/ipc/PBackgroundSharedTypes.h"
26
#include "nsContentUtils.h"
27
#include "nsDebug.h"
28
#include "nsError.h"
29
#include "nsIInputStream.h"
30
#include "nsIPrincipal.h"
31
#include "ReportInternalError.h"
32
33
namespace mozilla {
34
namespace dom {
35
36
using namespace mozilla::dom::indexedDB;
37
using namespace mozilla::dom::quota;
38
39
IDBMutableFile::IDBMutableFile(IDBDatabase* aDatabase,
40
                               BackgroundMutableFileChild* aActor,
41
                               const nsAString& aName,
42
                               const nsAString& aType)
43
  : DOMEventTargetHelper(aDatabase)
44
  , mDatabase(aDatabase)
45
  , mBackgroundActor(aActor)
46
  , mName(aName)
47
  , mType(aType)
48
  , mInvalidated(false)
49
0
{
50
0
  MOZ_ASSERT(aDatabase);
51
0
  aDatabase->AssertIsOnOwningThread();
52
0
  MOZ_ASSERT(aActor);
53
0
54
0
  mDatabase->NoteLiveMutableFile(this);
55
0
}
56
57
IDBMutableFile::~IDBMutableFile()
58
0
{
59
0
  AssertIsOnOwningThread();
60
0
61
0
  mDatabase->NoteFinishedMutableFile(this);
62
0
63
0
  if (mBackgroundActor) {
64
0
    mBackgroundActor->SendDeleteMeInternal();
65
0
    MOZ_ASSERT(!mBackgroundActor, "SendDeleteMeInternal should have cleared!");
66
0
  }
67
0
}
68
69
#ifdef DEBUG
70
71
void
72
IDBMutableFile::AssertIsOnOwningThread() const
73
{
74
  MOZ_ASSERT(mDatabase);
75
  mDatabase->AssertIsOnOwningThread();
76
}
77
78
#endif // DEBUG
79
80
int64_t
81
IDBMutableFile::GetFileId() const
82
0
{
83
0
  AssertIsOnOwningThread();
84
0
85
0
  int64_t fileId;
86
0
  if (!mBackgroundActor ||
87
0
      NS_WARN_IF(!mBackgroundActor->SendGetFileId(&fileId))) {
88
0
    return -1;
89
0
  }
90
0
91
0
  return fileId;
92
0
}
93
94
void
95
IDBMutableFile::Invalidate()
96
0
{
97
0
  AssertIsOnOwningThread();
98
0
  MOZ_ASSERT(!mInvalidated);
99
0
100
0
  mInvalidated = true;
101
0
102
0
  AbortFileHandles();
103
0
}
104
105
void
106
IDBMutableFile::RegisterFileHandle(IDBFileHandle* aFileHandle)
107
0
{
108
0
  AssertIsOnOwningThread();
109
0
  MOZ_ASSERT(aFileHandle);
110
0
  aFileHandle->AssertIsOnOwningThread();
111
0
  MOZ_ASSERT(!mFileHandles.Contains(aFileHandle));
112
0
113
0
  mFileHandles.PutEntry(aFileHandle);
114
0
}
115
116
void
117
IDBMutableFile::UnregisterFileHandle(IDBFileHandle* aFileHandle)
118
0
{
119
0
  AssertIsOnOwningThread();
120
0
  MOZ_ASSERT(aFileHandle);
121
0
  aFileHandle->AssertIsOnOwningThread();
122
0
  MOZ_ASSERT(mFileHandles.Contains(aFileHandle));
123
0
124
0
  mFileHandles.RemoveEntry(aFileHandle);
125
0
}
126
127
void
128
IDBMutableFile::AbortFileHandles()
129
0
{
130
0
  AssertIsOnOwningThread();
131
0
132
0
  class MOZ_STACK_CLASS Helper final
133
0
  {
134
0
  public:
135
0
    static void
136
0
    AbortFileHandles(nsTHashtable<nsPtrHashKey<IDBFileHandle>>& aTable)
137
0
    {
138
0
      if (!aTable.Count()) {
139
0
        return;
140
0
      }
141
0
142
0
      nsTArray<RefPtr<IDBFileHandle>> fileHandlesToAbort;
143
0
      fileHandlesToAbort.SetCapacity(aTable.Count());
144
0
145
0
      for (auto iter = aTable.Iter(); !iter.Done(); iter.Next()) {
146
0
        IDBFileHandle* fileHandle = iter.Get()->GetKey();
147
0
        MOZ_ASSERT(fileHandle);
148
0
149
0
        fileHandle->AssertIsOnOwningThread();
150
0
151
0
        if (!fileHandle->IsDone()) {
152
0
          fileHandlesToAbort.AppendElement(iter.Get()->GetKey());
153
0
        }
154
0
      }
155
0
      MOZ_ASSERT(fileHandlesToAbort.Length() <= aTable.Count());
156
0
157
0
      if (fileHandlesToAbort.IsEmpty()) {
158
0
        return;
159
0
      }
160
0
161
0
      for (RefPtr<IDBFileHandle>& fileHandle : fileHandlesToAbort) {
162
0
        MOZ_ASSERT(fileHandle);
163
0
164
0
        fileHandle->Abort();
165
0
      }
166
0
    }
167
0
  };
168
0
169
0
  Helper::AbortFileHandles(mFileHandles);
170
0
}
171
172
IDBDatabase*
173
IDBMutableFile::Database() const
174
0
{
175
0
  AssertIsOnOwningThread();
176
0
177
0
  return mDatabase;
178
0
}
179
180
already_AddRefed<IDBFileHandle>
181
IDBMutableFile::Open(FileMode aMode, ErrorResult& aError)
182
0
{
183
0
  AssertIsOnOwningThread();
184
0
185
0
  if (QuotaManager::IsShuttingDown() ||
186
0
      mDatabase->IsClosed() ||
187
0
      !GetOwner()) {
188
0
    aError.Throw(NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
189
0
    return nullptr;
190
0
  }
191
0
192
0
  RefPtr<IDBFileHandle> fileHandle =
193
0
    IDBFileHandle::Create(this, aMode);
194
0
  if (NS_WARN_IF(!fileHandle)) {
195
0
    aError.Throw(NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
196
0
    return nullptr;
197
0
  }
198
0
199
0
  BackgroundFileHandleChild* actor = new BackgroundFileHandleChild(fileHandle);
200
0
201
0
  MOZ_ALWAYS_TRUE(
202
0
    mBackgroundActor->SendPBackgroundFileHandleConstructor(actor, aMode));
203
0
204
0
  fileHandle->SetBackgroundActor(actor);
205
0
206
0
  return fileHandle.forget();
207
0
}
208
209
already_AddRefed<DOMRequest>
210
IDBMutableFile::GetFile(ErrorResult& aError)
211
0
{
212
0
  RefPtr<IDBFileHandle> fileHandle = Open(FileMode::Readonly, aError);
213
0
  if (NS_WARN_IF(aError.Failed())) {
214
0
    return nullptr;
215
0
  }
216
0
217
0
  FileRequestGetFileParams params;
218
0
219
0
  RefPtr<IDBFileRequest> request =
220
0
    IDBFileRequest::Create(fileHandle, /* aWrapAsDOMRequest */ true);
221
0
222
0
  fileHandle->StartRequest(request, params);
223
0
224
0
  return request.forget();
225
0
}
226
227
NS_IMPL_ADDREF_INHERITED(IDBMutableFile, DOMEventTargetHelper)
228
NS_IMPL_RELEASE_INHERITED(IDBMutableFile, DOMEventTargetHelper)
229
230
0
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IDBMutableFile)
231
0
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
232
233
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBMutableFile)
234
235
0
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBMutableFile,
236
0
                                                  DOMEventTargetHelper)
237
0
  tmp->AssertIsOnOwningThread();
238
0
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDatabase)
239
0
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
240
241
0
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBMutableFile,
242
0
                                                DOMEventTargetHelper)
243
0
  tmp->AssertIsOnOwningThread();
244
0
245
0
  // Don't unlink mDatabase!
246
0
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
247
248
JSObject*
249
IDBMutableFile::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
250
0
{
251
0
  return IDBMutableFile_Binding::Wrap(aCx, this, aGivenProto);
252
0
}
253
254
} // namespace dom
255
} // namespace mozilla