LCOV - code coverage report
Current view: top level - dom/indexedDB - IDBRequest.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 304 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 52 0.0 %
Legend: Lines: hit not hit

          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             : #include "IDBRequest.h"
       8             : 
       9             : #include "BackgroundChildImpl.h"
      10             : #include "IDBCursor.h"
      11             : #include "IDBDatabase.h"
      12             : #include "IDBEvents.h"
      13             : #include "IDBFactory.h"
      14             : #include "IDBIndex.h"
      15             : #include "IDBObjectStore.h"
      16             : #include "IDBTransaction.h"
      17             : #include "IndexedDatabaseManager.h"
      18             : #include "mozilla/ContentEvents.h"
      19             : #include "mozilla/ErrorResult.h"
      20             : #include "mozilla/EventDispatcher.h"
      21             : #include "mozilla/Move.h"
      22             : #include "mozilla/dom/DOMError.h"
      23             : #include "mozilla/dom/ErrorEventBinding.h"
      24             : #include "mozilla/dom/IDBOpenDBRequestBinding.h"
      25             : #include "mozilla/dom/ScriptSettings.h"
      26             : #include "nsCOMPtr.h"
      27             : #include "nsContentUtils.h"
      28             : #include "nsIScriptContext.h"
      29             : #include "nsJSUtils.h"
      30             : #include "nsPIDOMWindow.h"
      31             : #include "nsString.h"
      32             : #include "ReportInternalError.h"
      33             : #include "WorkerHolder.h"
      34             : #include "WorkerPrivate.h"
      35             : 
      36             : // Include this last to avoid path problems on Windows.
      37             : #include "ActorsChild.h"
      38             : 
      39             : namespace mozilla {
      40             : namespace dom {
      41             : 
      42             : using namespace mozilla::dom::indexedDB;
      43             : using namespace mozilla::dom::workers;
      44             : using namespace mozilla::ipc;
      45             : 
      46             : namespace {
      47             : 
      48             : NS_DEFINE_IID(kIDBRequestIID, PRIVATE_IDBREQUEST_IID);
      49             : 
      50             : } // namespace
      51             : 
      52           0 : IDBRequest::IDBRequest(IDBDatabase* aDatabase)
      53             :   : IDBWrapperCache(aDatabase)
      54             :   , mLoggingSerialNumber(0)
      55             :   , mLineNo(0)
      56             :   , mColumn(0)
      57           0 :   , mHaveResultOrErrorCode(false)
      58             : {
      59           0 :   MOZ_ASSERT(aDatabase);
      60           0 :   aDatabase->AssertIsOnOwningThread();
      61             : 
      62           0 :   InitMembers();
      63           0 : }
      64             : 
      65           0 : IDBRequest::IDBRequest(nsPIDOMWindowInner* aOwner)
      66             :   : IDBWrapperCache(aOwner)
      67             :   , mLoggingSerialNumber(0)
      68             :   , mLineNo(0)
      69             :   , mColumn(0)
      70           0 :   , mHaveResultOrErrorCode(false)
      71             : {
      72           0 :   InitMembers();
      73           0 : }
      74             : 
      75           0 : IDBRequest::~IDBRequest()
      76             : {
      77           0 :   AssertIsOnOwningThread();
      78           0 : }
      79             : 
      80             : void
      81           0 : IDBRequest::InitMembers()
      82             : {
      83           0 :   AssertIsOnOwningThread();
      84             : 
      85           0 :   mResultVal.setUndefined();
      86           0 :   mLoggingSerialNumber = NextSerialNumber();
      87           0 :   mErrorCode = NS_OK;
      88           0 :   mLineNo = 0;
      89           0 :   mColumn = 0;
      90           0 :   mHaveResultOrErrorCode = false;
      91           0 : }
      92             : 
      93             : // static
      94             : already_AddRefed<IDBRequest>
      95           0 : IDBRequest::Create(JSContext* aCx,
      96             :                    IDBDatabase* aDatabase,
      97             :                    IDBTransaction* aTransaction)
      98             : {
      99           0 :   MOZ_ASSERT(aCx);
     100           0 :   MOZ_ASSERT(aDatabase);
     101           0 :   aDatabase->AssertIsOnOwningThread();
     102             : 
     103           0 :   RefPtr<IDBRequest> request = new IDBRequest(aDatabase);
     104           0 :   CaptureCaller(aCx, request->mFilename, &request->mLineNo, &request->mColumn);
     105             : 
     106           0 :   request->mTransaction = aTransaction;
     107           0 :   request->SetScriptOwner(aDatabase->GetScriptOwner());
     108             : 
     109           0 :   return request.forget();
     110             : }
     111             : 
     112             : // static
     113             : already_AddRefed<IDBRequest>
     114           0 : IDBRequest::Create(JSContext* aCx,
     115             :                    IDBObjectStore* aSourceAsObjectStore,
     116             :                    IDBDatabase* aDatabase,
     117             :                    IDBTransaction* aTransaction)
     118             : {
     119           0 :   MOZ_ASSERT(aSourceAsObjectStore);
     120           0 :   aSourceAsObjectStore->AssertIsOnOwningThread();
     121             : 
     122           0 :   RefPtr<IDBRequest> request = Create(aCx, aDatabase, aTransaction);
     123             : 
     124           0 :   request->mSourceAsObjectStore = aSourceAsObjectStore;
     125             : 
     126           0 :   return request.forget();
     127             : }
     128             : 
     129             : // static
     130             : already_AddRefed<IDBRequest>
     131           0 : IDBRequest::Create(JSContext* aCx,
     132             :                    IDBIndex* aSourceAsIndex,
     133             :                    IDBDatabase* aDatabase,
     134             :                    IDBTransaction* aTransaction)
     135             : {
     136           0 :   MOZ_ASSERT(aSourceAsIndex);
     137           0 :   aSourceAsIndex->AssertIsOnOwningThread();
     138             : 
     139           0 :   RefPtr<IDBRequest> request = Create(aCx, aDatabase, aTransaction);
     140             : 
     141           0 :   request->mSourceAsIndex = aSourceAsIndex;
     142             : 
     143           0 :   return request.forget();
     144             : }
     145             : 
     146             : // static
     147             : uint64_t
     148           0 : IDBRequest::NextSerialNumber()
     149             : {
     150             :   BackgroundChildImpl::ThreadLocal* threadLocal =
     151           0 :     BackgroundChildImpl::GetThreadLocalForCurrentThread();
     152           0 :   MOZ_ASSERT(threadLocal);
     153             : 
     154           0 :   ThreadLocal* idbThreadLocal = threadLocal->mIndexedDBThreadLocal;
     155           0 :   MOZ_ASSERT(idbThreadLocal);
     156             : 
     157           0 :   return idbThreadLocal->NextRequestSN();
     158             : }
     159             : 
     160             : void
     161           0 : IDBRequest::SetLoggingSerialNumber(uint64_t aLoggingSerialNumber)
     162             : {
     163           0 :   AssertIsOnOwningThread();
     164           0 :   MOZ_ASSERT(aLoggingSerialNumber > mLoggingSerialNumber);
     165             : 
     166           0 :   mLoggingSerialNumber = aLoggingSerialNumber;
     167           0 : }
     168             : 
     169             : void
     170           0 : IDBRequest::CaptureCaller(JSContext* aCx, nsAString& aFilename,
     171             :                           uint32_t* aLineNo, uint32_t* aColumn)
     172             : {
     173           0 :   MOZ_ASSERT(aFilename.IsEmpty());
     174           0 :   MOZ_ASSERT(aLineNo);
     175           0 :   MOZ_ASSERT(aColumn);
     176             : 
     177           0 :   nsJSUtils::GetCallingLocation(aCx, aFilename, aLineNo, aColumn);
     178           0 : }
     179             : 
     180             : void
     181           0 : IDBRequest::GetSource(
     182             :              Nullable<OwningIDBObjectStoreOrIDBIndexOrIDBCursor>& aSource) const
     183             : {
     184           0 :   AssertIsOnOwningThread();
     185             : 
     186           0 :   MOZ_ASSERT_IF(mSourceAsObjectStore, !mSourceAsIndex);
     187           0 :   MOZ_ASSERT_IF(mSourceAsIndex, !mSourceAsObjectStore);
     188           0 :   MOZ_ASSERT_IF(mSourceAsCursor, mSourceAsObjectStore || mSourceAsIndex);
     189             : 
     190             :   // Always check cursor first since cursor requests hold both the cursor and
     191             :   // the objectStore or index the cursor came from.
     192           0 :   if (mSourceAsCursor) {
     193           0 :     aSource.SetValue().SetAsIDBCursor() = mSourceAsCursor;
     194           0 :   } else if (mSourceAsObjectStore) {
     195           0 :     aSource.SetValue().SetAsIDBObjectStore() = mSourceAsObjectStore;
     196           0 :   } else if (mSourceAsIndex) {
     197           0 :     aSource.SetValue().SetAsIDBIndex() = mSourceAsIndex;
     198             :   } else {
     199           0 :     aSource.SetNull();
     200             :   }
     201           0 : }
     202             : 
     203             : void
     204           0 : IDBRequest::Reset()
     205             : {
     206           0 :   AssertIsOnOwningThread();
     207             : 
     208           0 :   mResultVal.setUndefined();
     209           0 :   mHaveResultOrErrorCode = false;
     210           0 :   mError = nullptr;
     211           0 : }
     212             : 
     213             : void
     214           0 : IDBRequest::SetError(nsresult aRv)
     215             : {
     216           0 :   AssertIsOnOwningThread();
     217           0 :   MOZ_ASSERT(NS_FAILED(aRv));
     218           0 :   MOZ_ASSERT(NS_ERROR_GET_MODULE(aRv) == NS_ERROR_MODULE_DOM_INDEXEDDB);
     219           0 :   MOZ_ASSERT(!mError);
     220             : 
     221           0 :   mHaveResultOrErrorCode = true;
     222           0 :   mError = new DOMError(GetOwner(), aRv);
     223           0 :   mErrorCode = aRv;
     224             : 
     225           0 :   mResultVal.setUndefined();
     226           0 : }
     227             : 
     228             : #ifdef DEBUG
     229             : 
     230             : nsresult
     231           0 : IDBRequest::GetErrorCode() const
     232             : {
     233           0 :   AssertIsOnOwningThread();
     234           0 :   MOZ_ASSERT(mHaveResultOrErrorCode);
     235             : 
     236           0 :   return mErrorCode;
     237             : }
     238             : 
     239             : DOMError*
     240           0 : IDBRequest::GetErrorAfterResult() const
     241             : {
     242           0 :   AssertIsOnOwningThread();
     243           0 :   MOZ_ASSERT(mHaveResultOrErrorCode);
     244             : 
     245           0 :   return mError;
     246             : }
     247             : 
     248             : #endif // DEBUG
     249             : 
     250             : void
     251           0 : IDBRequest::GetCallerLocation(nsAString& aFilename, uint32_t* aLineNo,
     252             :                               uint32_t* aColumn) const
     253             : {
     254           0 :   AssertIsOnOwningThread();
     255           0 :   MOZ_ASSERT(aLineNo);
     256           0 :   MOZ_ASSERT(aColumn);
     257             : 
     258           0 :   aFilename = mFilename;
     259           0 :   *aLineNo = mLineNo;
     260           0 :   *aColumn = mColumn;
     261           0 : }
     262             : 
     263             : IDBRequestReadyState
     264           0 : IDBRequest::ReadyState() const
     265             : {
     266           0 :   AssertIsOnOwningThread();
     267             : 
     268           0 :   return IsPending() ?
     269             :     IDBRequestReadyState::Pending :
     270           0 :     IDBRequestReadyState::Done;
     271             : }
     272             : 
     273             : void
     274           0 : IDBRequest::SetSource(IDBCursor* aSource)
     275             : {
     276           0 :   AssertIsOnOwningThread();
     277           0 :   MOZ_ASSERT(aSource);
     278           0 :   MOZ_ASSERT(mSourceAsObjectStore || mSourceAsIndex);
     279           0 :   MOZ_ASSERT(!mSourceAsCursor);
     280             : 
     281           0 :   mSourceAsCursor = aSource;
     282           0 : }
     283             : 
     284             : JSObject*
     285           0 : IDBRequest::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
     286             : {
     287           0 :   return IDBRequestBinding::Wrap(aCx, this, aGivenProto);
     288             : }
     289             : 
     290             : void
     291           0 : IDBRequest::GetResult(JS::MutableHandle<JS::Value> aResult,
     292             :                       ErrorResult& aRv) const
     293             : {
     294           0 :   AssertIsOnOwningThread();
     295             : 
     296           0 :   if (!mHaveResultOrErrorCode) {
     297           0 :     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     298           0 :     return;
     299             :   }
     300             : 
     301           0 :   aResult.set(mResultVal);
     302             : }
     303             : 
     304             : void
     305           0 : IDBRequest::SetResultCallback(ResultCallback* aCallback)
     306             : {
     307           0 :   AssertIsOnOwningThread();
     308           0 :   MOZ_ASSERT(aCallback);
     309           0 :   MOZ_ASSERT(!mHaveResultOrErrorCode);
     310           0 :   MOZ_ASSERT(mResultVal.isUndefined());
     311           0 :   MOZ_ASSERT(!mError);
     312             : 
     313             :   // See if our window is still valid.
     314           0 :   if (NS_WARN_IF(NS_FAILED(CheckInnerWindowCorrectness()))) {
     315           0 :     SetError(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
     316           0 :     return;
     317             :   }
     318             : 
     319           0 :   AutoJSAPI autoJS;
     320           0 :   Maybe<JSAutoCompartment> ac;
     321             : 
     322           0 :   if (GetScriptOwner()) {
     323             :     // If we have a script owner we want the SafeJSContext and then to enter the
     324             :     // script owner's compartment.
     325           0 :     autoJS.Init();
     326           0 :     ac.emplace(autoJS.cx(), GetScriptOwner());
     327             :   } else {
     328             :     // Otherwise our owner is a window and we use that to initialize.
     329           0 :     MOZ_ASSERT(GetOwner());
     330           0 :     if (!autoJS.Init(GetOwner())) {
     331           0 :       IDB_WARNING("Failed to initialize AutoJSAPI!");
     332           0 :       SetError(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
     333           0 :       return;
     334             :     }
     335             :   }
     336             : 
     337           0 :   JSContext* cx = autoJS.cx();
     338             : 
     339           0 :   AssertIsRooted();
     340             : 
     341           0 :   JS::Rooted<JS::Value> result(cx);
     342           0 :   nsresult rv = aCallback->GetResult(cx, &result);
     343           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     344             :     // This can only fail if the structured clone contains a mutable file
     345             :     // and the child is not in the main thread and main process.
     346             :     // In that case CreateAndWrapMutableFile() returns false which shows up
     347             :     // as NS_ERROR_DOM_DATA_CLONE_ERR here.
     348           0 :     MOZ_ASSERT(rv == NS_ERROR_DOM_DATA_CLONE_ERR);
     349             : 
     350             :     // We are not setting a result or an error object here since we want to
     351             :     // throw an exception when the 'result' property is being touched.
     352           0 :     return;
     353             :   }
     354             : 
     355           0 :   mError = nullptr;
     356           0 :   mResultVal = result;
     357             : 
     358           0 :   mHaveResultOrErrorCode = true;
     359             : }
     360             : 
     361             : DOMError*
     362           0 : IDBRequest::GetError(ErrorResult& aRv)
     363             : {
     364           0 :   AssertIsOnOwningThread();
     365             : 
     366           0 :   if (!mHaveResultOrErrorCode) {
     367           0 :     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     368           0 :     return nullptr;
     369             :   }
     370             : 
     371           0 :   return mError;
     372             : }
     373             : 
     374             : NS_IMPL_CYCLE_COLLECTION_CLASS(IDBRequest)
     375             : 
     376           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBRequest, IDBWrapperCache)
     377           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSourceAsObjectStore)
     378           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSourceAsIndex)
     379           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSourceAsCursor)
     380           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTransaction)
     381           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mError)
     382           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     383             : 
     384           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBRequest, IDBWrapperCache)
     385           0 :   tmp->mResultVal.setUndefined();
     386           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mSourceAsObjectStore)
     387           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mSourceAsIndex)
     388           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mSourceAsCursor)
     389           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mTransaction)
     390           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mError)
     391           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     392             : 
     393           0 : NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(IDBRequest, IDBWrapperCache)
     394             :   // Don't need NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER because
     395             :   // DOMEventTargetHelper does it for us.
     396           0 :   NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mResultVal)
     397           0 : NS_IMPL_CYCLE_COLLECTION_TRACE_END
     398             : 
     399           0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBRequest)
     400           0 :   if (aIID.Equals(kIDBRequestIID)) {
     401           0 :     foundInterface = this;
     402             :   } else
     403           0 : NS_INTERFACE_MAP_END_INHERITING(IDBWrapperCache)
     404             : 
     405           0 : NS_IMPL_ADDREF_INHERITED(IDBRequest, IDBWrapperCache)
     406           0 : NS_IMPL_RELEASE_INHERITED(IDBRequest, IDBWrapperCache)
     407             : 
     408             : nsresult
     409           0 : IDBRequest::GetEventTargetParent(EventChainPreVisitor& aVisitor)
     410             : {
     411           0 :   AssertIsOnOwningThread();
     412             : 
     413           0 :   aVisitor.mCanHandle = true;
     414           0 :   aVisitor.mParentTarget = mTransaction;
     415           0 :   return NS_OK;
     416             : }
     417             : 
     418             : class IDBOpenDBRequest::WorkerHolder final
     419             :   : public mozilla::dom::workers::WorkerHolder
     420             : {
     421             :   WorkerPrivate* mWorkerPrivate;
     422             : #ifdef DEBUG
     423             :   // This is only here so that assertions work in the destructor even if
     424             :   // NoteAddWorkerHolderFailed was called.
     425             :   WorkerPrivate* mWorkerPrivateDEBUG;
     426             : #endif
     427             : 
     428             : public:
     429             :   explicit
     430           0 :   WorkerHolder(WorkerPrivate* aWorkerPrivate)
     431           0 :     : mWorkerPrivate(aWorkerPrivate)
     432             : #ifdef DEBUG
     433           0 :     , mWorkerPrivateDEBUG(aWorkerPrivate)
     434             : #endif
     435             :   {
     436           0 :     MOZ_ASSERT(aWorkerPrivate);
     437           0 :     aWorkerPrivate->AssertIsOnWorkerThread();
     438             : 
     439           0 :     MOZ_COUNT_CTOR(IDBOpenDBRequest::WorkerHolder);
     440           0 :   }
     441             : 
     442           0 :   ~WorkerHolder()
     443           0 :   {
     444             : #ifdef DEBUG
     445           0 :     mWorkerPrivateDEBUG->AssertIsOnWorkerThread();
     446             : #endif
     447             : 
     448           0 :     MOZ_COUNT_DTOR(IDBOpenDBRequest::WorkerHolder);
     449           0 :   }
     450             : 
     451             :   void
     452           0 :   NoteAddWorkerHolderFailed()
     453             :   {
     454           0 :     MOZ_ASSERT(mWorkerPrivate);
     455           0 :     mWorkerPrivate->AssertIsOnWorkerThread();
     456             : 
     457           0 :     mWorkerPrivate = nullptr;
     458           0 :   }
     459             : 
     460             : private:
     461             :   virtual bool
     462             :   Notify(Status aStatus) override;
     463             : };
     464             : 
     465           0 : IDBOpenDBRequest::IDBOpenDBRequest(IDBFactory* aFactory,
     466             :                                    nsPIDOMWindowInner* aOwner,
     467           0 :                                    bool aFileHandleDisabled)
     468             :   : IDBRequest(aOwner)
     469             :   , mFactory(aFactory)
     470             :   , mFileHandleDisabled(aFileHandleDisabled)
     471           0 :   , mIncreasedActiveDatabaseCount(false)
     472             : {
     473           0 :   AssertIsOnOwningThread();
     474           0 :   MOZ_ASSERT(aFactory);
     475             : 
     476             :   // aOwner may be null.
     477           0 : }
     478             : 
     479           0 : IDBOpenDBRequest::~IDBOpenDBRequest()
     480             : {
     481           0 :   AssertIsOnOwningThread();
     482           0 :   MOZ_ASSERT(!mIncreasedActiveDatabaseCount);
     483           0 : }
     484             : 
     485             : // static
     486             : already_AddRefed<IDBOpenDBRequest>
     487           0 : IDBOpenDBRequest::CreateForWindow(JSContext* aCx,
     488             :                                   IDBFactory* aFactory,
     489             :                                   nsPIDOMWindowInner* aOwner,
     490             :                                   JS::Handle<JSObject*> aScriptOwner)
     491             : {
     492           0 :   MOZ_ASSERT(aFactory);
     493           0 :   aFactory->AssertIsOnOwningThread();
     494           0 :   MOZ_ASSERT(aOwner);
     495           0 :   MOZ_ASSERT(aScriptOwner);
     496             : 
     497           0 :   bool fileHandleDisabled = !IndexedDatabaseManager::IsFileHandleEnabled();
     498             : 
     499             :   RefPtr<IDBOpenDBRequest> request =
     500           0 :     new IDBOpenDBRequest(aFactory, aOwner, fileHandleDisabled);
     501           0 :   CaptureCaller(aCx, request->mFilename, &request->mLineNo, &request->mColumn);
     502             : 
     503           0 :   request->SetScriptOwner(aScriptOwner);
     504             : 
     505           0 :   request->IncreaseActiveDatabaseCount();
     506             : 
     507           0 :   return request.forget();
     508             : }
     509             : 
     510             : // static
     511             : already_AddRefed<IDBOpenDBRequest>
     512           0 : IDBOpenDBRequest::CreateForJS(JSContext* aCx,
     513             :                               IDBFactory* aFactory,
     514             :                               JS::Handle<JSObject*> aScriptOwner)
     515             : {
     516           0 :   MOZ_ASSERT(aFactory);
     517           0 :   aFactory->AssertIsOnOwningThread();
     518           0 :   MOZ_ASSERT(aScriptOwner);
     519             : 
     520           0 :   bool fileHandleDisabled = !IndexedDatabaseManager::IsFileHandleEnabled();
     521             : 
     522             :   RefPtr<IDBOpenDBRequest> request =
     523           0 :     new IDBOpenDBRequest(aFactory, nullptr, fileHandleDisabled);
     524           0 :   CaptureCaller(aCx, request->mFilename, &request->mLineNo, &request->mColumn);
     525             : 
     526           0 :   request->SetScriptOwner(aScriptOwner);
     527             : 
     528           0 :   if (!NS_IsMainThread()) {
     529           0 :     WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
     530           0 :     MOZ_ASSERT(workerPrivate);
     531             : 
     532           0 :     workerPrivate->AssertIsOnWorkerThread();
     533             : 
     534           0 :     nsAutoPtr<WorkerHolder> workerHolder(new WorkerHolder(workerPrivate));
     535           0 :     if (NS_WARN_IF(!workerHolder->HoldWorker(workerPrivate, Canceling))) {
     536           0 :       workerHolder->NoteAddWorkerHolderFailed();
     537           0 :       return nullptr;
     538             :     }
     539             : 
     540           0 :     request->mWorkerHolder = Move(workerHolder);
     541             :   }
     542             : 
     543           0 :   request->IncreaseActiveDatabaseCount();
     544             : 
     545           0 :   return request.forget();
     546             : }
     547             : 
     548             : void
     549           0 : IDBOpenDBRequest::SetTransaction(IDBTransaction* aTransaction)
     550             : {
     551           0 :   AssertIsOnOwningThread();
     552             : 
     553           0 :   MOZ_ASSERT(!aTransaction || !mTransaction);
     554             : 
     555           0 :   mTransaction = aTransaction;
     556           0 : }
     557             : 
     558             : void
     559           0 : IDBOpenDBRequest::DispatchNonTransactionError(nsresult aErrorCode)
     560             : {
     561           0 :   AssertIsOnOwningThread();
     562           0 :   MOZ_ASSERT(NS_FAILED(aErrorCode));
     563           0 :   MOZ_ASSERT(NS_ERROR_GET_MODULE(aErrorCode) == NS_ERROR_MODULE_DOM_INDEXEDDB);
     564             : 
     565             :   // The actor failed to initiate, decrease the number of active IDBOpenRequests
     566             :   // here since NoteComplete won't be called.
     567           0 :   MaybeDecreaseActiveDatabaseCount();
     568             : 
     569           0 :   SetError(aErrorCode);
     570             : 
     571             :   // Make an error event and fire it at the target.
     572             :   nsCOMPtr<nsIDOMEvent> event =
     573           0 :     CreateGenericEvent(this,
     574           0 :                        nsDependentString(kErrorEventType),
     575             :                        eDoesBubble,
     576           0 :                        eCancelable);
     577           0 :   MOZ_ASSERT(event);
     578             : 
     579             :   bool ignored;
     580           0 :   if (NS_FAILED(DispatchEvent(event, &ignored))) {
     581           0 :     NS_WARNING("Failed to dispatch event!");
     582             :   }
     583           0 : }
     584             : 
     585             : void
     586           0 : IDBOpenDBRequest::NoteComplete()
     587             : {
     588           0 :   AssertIsOnOwningThread();
     589           0 :   MOZ_ASSERT_IF(!NS_IsMainThread(), mWorkerHolder);
     590             : 
     591             :   // Normally, we decrease the number of active IDBOpenRequests here.
     592           0 :   MaybeDecreaseActiveDatabaseCount();
     593             : 
     594             :   // If we have a WorkerHolder installed on the worker then nulling this out
     595             :   // will uninstall it from the worker.
     596           0 :   mWorkerHolder = nullptr;
     597           0 : }
     598             : 
     599             : void
     600           0 : IDBOpenDBRequest::IncreaseActiveDatabaseCount()
     601             : {
     602           0 :   AssertIsOnOwningThread();
     603           0 :   MOZ_ASSERT(!mIncreasedActiveDatabaseCount);
     604             : 
     605             :   // Increase the number of active IDBOpenRequests.
     606             :   // Note: We count here instead of the actor's ctor because the preemption
     607             :   // could happen at next JS interrupt but its BackgroundFactoryRequestChild
     608             :   // could be created asynchronously from IDBFactory::BackgroundCreateCallback
     609             :   // ::ActorCreated() if its PBackgroundChild is not created yet on this thread.
     610           0 :   mFactory->UpdateActiveDatabaseCount(1);
     611           0 :   mIncreasedActiveDatabaseCount = true;
     612           0 : }
     613             : 
     614             : void
     615           0 : IDBOpenDBRequest::MaybeDecreaseActiveDatabaseCount()
     616             : {
     617           0 :   AssertIsOnOwningThread();
     618             : 
     619           0 :   if (mIncreasedActiveDatabaseCount) {
     620             :     // Decrease the number of active IDBOpenRequests.
     621           0 :     mFactory->UpdateActiveDatabaseCount(-1);
     622           0 :     mIncreasedActiveDatabaseCount = false;
     623             :   }
     624           0 : }
     625             : 
     626             : NS_IMPL_CYCLE_COLLECTION_CLASS(IDBOpenDBRequest)
     627             : 
     628           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBOpenDBRequest,
     629             :                                                   IDBRequest)
     630           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFactory)
     631           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     632             : 
     633           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBOpenDBRequest,
     634             :                                                 IDBRequest)
     635             :   // Don't unlink mFactory!
     636           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     637             : 
     638           0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBOpenDBRequest)
     639           0 : NS_INTERFACE_MAP_END_INHERITING(IDBRequest)
     640             : 
     641           0 : NS_IMPL_ADDREF_INHERITED(IDBOpenDBRequest, IDBRequest)
     642           0 : NS_IMPL_RELEASE_INHERITED(IDBOpenDBRequest, IDBRequest)
     643             : 
     644             : nsresult
     645           0 : IDBOpenDBRequest::PostHandleEvent(EventChainPostVisitor& aVisitor)
     646             : {
     647             :   nsresult rv =
     648           0 :     IndexedDatabaseManager::CommonPostHandleEvent(aVisitor, mFactory);
     649           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     650           0 :     return rv;
     651             :   }
     652             : 
     653           0 :   return NS_OK;
     654             : }
     655             : 
     656             : JSObject*
     657           0 : IDBOpenDBRequest::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
     658             : {
     659           0 :   AssertIsOnOwningThread();
     660             : 
     661           0 :   return IDBOpenDBRequestBinding::Wrap(aCx, this, aGivenProto);
     662             : }
     663             : 
     664             : bool
     665           0 : IDBOpenDBRequest::
     666             : WorkerHolder::Notify(Status aStatus)
     667             : {
     668           0 :   MOZ_ASSERT(mWorkerPrivate);
     669           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     670           0 :   MOZ_ASSERT(aStatus > Running);
     671             : 
     672             :   // There's nothing we can really do here at the moment...
     673           0 :   NS_WARNING("Worker closing but IndexedDB is waiting to open a database!");
     674             : 
     675           0 :   return true;
     676             : }
     677             : 
     678             : } // namespace dom
     679             : } // namespace mozilla

Generated by: LCOV version 1.13