LCOV - code coverage report
Current view: directory - dom/indexedDB - IDBRequest.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 168 151 89.9 %
Date: 2012-06-02 Functions: 42 37 88.1 %

       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                 : /* ***** BEGIN LICENSE BLOCK *****
       4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       5                 :  *
       6                 :  * The contents of this file are subject to the Mozilla Public License Version
       7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       8                 :  * the License. You may obtain a copy of the License at
       9                 :  * http://www.mozilla.org/MPL/
      10                 :  *
      11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      13                 :  * for the specific language governing rights and limitations under the
      14                 :  * License.
      15                 :  *
      16                 :  * The Original Code is Indexed Database.
      17                 :  *
      18                 :  * The Initial Developer of the Original Code is
      19                 :  * The Mozilla Foundation.
      20                 :  * Portions created by the Initial Developer are Copyright (C) 2010
      21                 :  * the Initial Developer. All Rights Reserved.
      22                 :  *
      23                 :  * Contributor(s):
      24                 :  *   Shawn Wilsher <me@shawnwilsher.com>
      25                 :  *   Ben Turner <bent.mozilla@gmail.com>
      26                 :  *
      27                 :  * Alternatively, the contents of this file may be used under the terms of
      28                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      29                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      30                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      31                 :  * of those above. If you wish to allow use of your version of this file only
      32                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      33                 :  * use your version of this file under the terms of the MPL, indicate your
      34                 :  * decision by deleting the provisions above and replace them with the notice
      35                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      36                 :  * the provisions above, a recipient may use your version of this file under
      37                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      38                 :  *
      39                 :  * ***** END LICENSE BLOCK ***** */
      40                 : 
      41                 : #include "IDBRequest.h"
      42                 : 
      43                 : #include "nsIJSContextStack.h"
      44                 : #include "nsIScriptContext.h"
      45                 : 
      46                 : #include "nsComponentManagerUtils.h"
      47                 : #include "nsDOMClassInfoID.h"
      48                 : #include "nsDOMJSUtils.h"
      49                 : #include "nsContentUtils.h"
      50                 : #include "nsEventDispatcher.h"
      51                 : #include "nsPIDOMWindow.h"
      52                 : #include "nsStringGlue.h"
      53                 : #include "nsThreadUtils.h"
      54                 : #include "nsWrapperCacheInlines.h"
      55                 : 
      56                 : #include "AsyncConnectionHelper.h"
      57                 : #include "IDBEvents.h"
      58                 : #include "IDBTransaction.h"
      59                 : 
      60                 : USING_INDEXEDDB_NAMESPACE
      61                 : 
      62            2464 : IDBRequest::IDBRequest()
      63                 : : mResultVal(JSVAL_VOID),
      64                 :   mErrorCode(0),
      65                 :   mHaveResultOrErrorCode(false),
      66            2464 :   mRooted(false)
      67                 : {
      68            2464 :   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
      69            2464 : }
      70                 : 
      71            7316 : IDBRequest::~IDBRequest()
      72                 : {
      73            2464 :   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
      74                 : 
      75            2464 :   UnrootResultVal();
      76            9704 : }
      77                 : 
      78                 : // static
      79                 : already_AddRefed<IDBRequest>
      80            2388 : IDBRequest::Create(nsISupports* aSource,
      81                 :                    IDBWrapperCache* aOwnerCache,
      82                 :                    IDBTransaction* aTransaction)
      83                 : {
      84            2388 :   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
      85            4776 :   nsRefPtr<IDBRequest> request(new IDBRequest());
      86                 : 
      87            2388 :   request->mSource = aSource;
      88            2388 :   request->mTransaction = aTransaction;
      89            2388 :   request->BindToOwner(aOwnerCache);
      90            2388 :   if (!request->SetScriptOwner(aOwnerCache->GetScriptOwner())) {
      91               0 :     return nsnull;
      92                 :   }
      93                 : 
      94            2388 :   return request.forget();
      95                 : }
      96                 : 
      97                 : void
      98            1778 : IDBRequest::Reset()
      99                 : {
     100            1778 :   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
     101            1778 :   mResultVal = JSVAL_VOID;
     102            1778 :   mHaveResultOrErrorCode = false;
     103            1778 :   mErrorCode = 0;
     104            1778 :   UnrootResultVal();
     105            1778 : }
     106                 : 
     107                 : nsresult
     108            4242 : IDBRequest::NotifyHelperCompleted(HelperBase* aHelper)
     109                 : {
     110            4242 :   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
     111            4242 :   NS_ASSERTION(!mHaveResultOrErrorCode, "Already called!");
     112            4242 :   NS_ASSERTION(!PreservingWrapper(), "Already rooted?!");
     113            4242 :   NS_ASSERTION(JSVAL_IS_VOID(mResultVal), "Should be undefined!");
     114                 : 
     115                 :   // See if our window is still valid. If not then we're going to pretend that
     116                 :   // we never completed.
     117            4242 :   if (NS_FAILED(CheckInnerWindowCorrectness())) {
     118               0 :     return NS_OK;
     119                 :   }
     120                 : 
     121            4242 :   mHaveResultOrErrorCode = true;
     122                 : 
     123            4242 :   nsresult rv = aHelper->GetResultCode();
     124                 : 
     125                 :   // If the request failed then set the error code and return.
     126            4242 :   if (NS_FAILED(rv)) {
     127              31 :     mErrorCode = NS_ERROR_GET_CODE(rv);
     128              31 :     return NS_OK;
     129                 :   }
     130                 : 
     131                 :   // Otherwise we need to get the result from the helper.
     132                 :   JSContext* cx;
     133            4211 :   if (GetScriptOwner()) {
     134            4211 :     nsIThreadJSContextStack* cxStack = nsContentUtils::ThreadJSContextStack();
     135            4211 :     NS_ASSERTION(cxStack, "Failed to get thread context stack!");
     136                 : 
     137            4211 :     if (NS_FAILED(cxStack->GetSafeJSContext(&cx))) {
     138               0 :       NS_WARNING("Failed to get safe JSContext!");
     139               0 :       rv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
     140               0 :       mErrorCode = NS_ERROR_GET_CODE(rv);
     141               0 :       return rv;
     142                 :     }
     143                 :   }
     144                 :   else {
     145               0 :     nsIScriptContext* sc = GetContextForEventHandlers(&rv);
     146               0 :     NS_ENSURE_STATE(sc);
     147               0 :     cx = sc->GetNativeContext();
     148               0 :     NS_ASSERTION(cx, "Failed to get a context!");
     149                 :   } 
     150                 : 
     151            4211 :   JSObject* global = GetParentObject();
     152            4211 :   NS_ASSERTION(global, "This should never be null!");
     153                 : 
     154            8422 :   JSAutoRequest ar(cx);
     155            8422 :   JSAutoEnterCompartment ac;
     156            4211 :   if (ac.enter(cx, global)) {
     157            4211 :     RootResultVal();
     158                 : 
     159            4211 :     rv = aHelper->GetSuccessResult(cx, &mResultVal);
     160            4211 :     if (NS_FAILED(rv)) {
     161               0 :       NS_WARNING("GetSuccessResult failed!");
     162                 :     }
     163                 :   }
     164                 :   else {
     165               0 :     NS_WARNING("Failed to enter correct compartment!");
     166               0 :     rv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
     167                 :   }
     168                 : 
     169            4211 :   if (NS_SUCCEEDED(rv)) {
     170            4211 :     mErrorCode = 0;
     171                 :   }
     172                 :   else {
     173               0 :     mErrorCode = NS_ERROR_GET_CODE(rv);
     174               0 :     mResultVal = JSVAL_VOID;
     175                 :   }
     176                 : 
     177            4211 :   return rv;
     178                 : }
     179                 : 
     180                 : void
     181            4136 : IDBRequest::RootResultValInternal()
     182                 : {
     183            4136 :   NS_HOLD_JS_OBJECTS(this, IDBRequest);
     184            4136 : }
     185                 : 
     186                 : void
     187            4136 : IDBRequest::UnrootResultValInternal()
     188                 : {
     189            4136 :   NS_DROP_JS_OBJECTS(this, IDBRequest);
     190            4136 : }
     191                 : 
     192                 : NS_IMETHODIMP
     193            1784 : IDBRequest::GetReadyState(nsAString& aReadyState)
     194                 : {
     195            1784 :   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
     196                 : 
     197            1784 :   if (mHaveResultOrErrorCode) {
     198            1781 :     aReadyState.AssignLiteral("done");
     199                 :   }
     200                 :   else {
     201               3 :     aReadyState.AssignLiteral("pending");
     202                 :   }
     203                 : 
     204            1784 :   return NS_OK;
     205                 : }
     206                 : 
     207                 : NS_IMETHODIMP
     208               4 : IDBRequest::GetSource(nsISupports** aSource)
     209                 : {
     210               4 :   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
     211                 : 
     212               8 :   nsCOMPtr<nsISupports> source(mSource);
     213               4 :   source.forget(aSource);
     214               4 :   return NS_OK;
     215                 : }
     216                 : 
     217                 : NS_IMETHODIMP
     218             588 : IDBRequest::GetTransaction(nsIIDBTransaction** aTransaction)
     219                 : {
     220             588 :   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
     221                 : 
     222            1176 :   nsCOMPtr<nsIIDBTransaction> transaction(mTransaction);
     223             588 :   transaction.forget(aTransaction);
     224             588 :   return NS_OK;
     225                 : }
     226                 : 
     227                 : NS_IMETHODIMP
     228            3099 : IDBRequest::GetResult(jsval* aResult)
     229                 : {
     230            3099 :   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
     231                 : 
     232            3099 :   if (!mHaveResultOrErrorCode) {
     233                 :     // XXX Need a real error code here.
     234               1 :     return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
     235                 :   }
     236                 : 
     237            3098 :   *aResult = mResultVal;
     238            3098 :   return NS_OK;
     239                 : }
     240                 : 
     241                 : NS_IMETHODIMP
     242              21 : IDBRequest::GetErrorCode(PRUint16* aErrorCode)
     243                 : {
     244              21 :   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
     245                 : 
     246              21 :   if (!mHaveResultOrErrorCode) {
     247                 :     // XXX Need a real error code here.
     248               0 :     return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
     249                 :   }
     250                 : 
     251              21 :   *aErrorCode = mErrorCode;
     252              21 :   return NS_OK;
     253                 : }
     254                 : 
     255            1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(IDBRequest)
     256                 : 
     257              31 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBRequest, IDBWrapperCache)
     258                 :   // Don't need NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS because
     259                 :   // nsDOMEventTargetHelper does it for us.
     260              31 :   NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(success)
     261              31 :   NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(error)
     262              31 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mSource)
     263              31 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mTransaction,
     264                 :                                                        nsPIDOMEventTarget)
     265              31 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     266                 : 
     267              31 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBRequest, IDBWrapperCache)
     268              31 :   tmp->mResultVal = JSVAL_VOID;
     269              31 :   tmp->UnrootResultVal();
     270              31 :   NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(success)
     271              31 :   NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(error)
     272              31 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mSource)
     273              31 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTransaction)
     274              31 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     275                 : 
     276            2693 : NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(IDBRequest, IDBWrapperCache)
     277                 :   // Don't need NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER because
     278                 :   // nsDOMEventTargetHelper does it for us.
     279            2693 :   if (JSVAL_IS_GCTHING(tmp->mResultVal)) {
     280             611 :     void *gcThing = JSVAL_TO_GCTHING(tmp->mResultVal);
     281             611 :     NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(gcThing, "mResultVal")
     282                 :   }
     283            2693 : NS_IMPL_CYCLE_COLLECTION_TRACE_END
     284                 : 
     285          146124 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBRequest)
     286           87413 :   NS_INTERFACE_MAP_ENTRY(nsIIDBRequest)
     287           75788 :   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBRequest)
     288           73400 : NS_INTERFACE_MAP_END_INHERITING(IDBWrapperCache)
     289                 : 
     290          102865 : NS_IMPL_ADDREF_INHERITED(IDBRequest, IDBWrapperCache)
     291          102865 : NS_IMPL_RELEASE_INHERITED(IDBRequest, IDBWrapperCache)
     292                 : 
     293                 : DOMCI_DATA(IDBRequest, IDBRequest)
     294                 : 
     295            1319 : NS_IMPL_EVENT_HANDLER(IDBRequest, success);
     296            1814 : NS_IMPL_EVENT_HANDLER(IDBRequest, error);
     297                 : 
     298                 : nsresult
     299            4314 : IDBRequest::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
     300                 : {
     301            4314 :   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
     302                 : 
     303            4314 :   aVisitor.mCanHandle = true;
     304            4314 :   aVisitor.mParentTarget = mTransaction;
     305            4314 :   return NS_OK;
     306                 : }
     307                 : 
     308             228 : IDBOpenDBRequest::~IDBOpenDBRequest()
     309                 : {
     310              76 :   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
     311                 : 
     312              76 :   UnrootResultVal();
     313             304 : }
     314                 : 
     315                 : // static
     316                 : already_AddRefed<IDBOpenDBRequest>
     317              76 : IDBOpenDBRequest::Create(nsPIDOMWindow* aOwner,
     318                 :                          JSObject* aScriptOwner)
     319                 : {
     320              76 :   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
     321             152 :   nsRefPtr<IDBOpenDBRequest> request(new IDBOpenDBRequest());
     322                 : 
     323              76 :   request->BindToOwner(aOwner);
     324              76 :   if (!request->SetScriptOwner(aScriptOwner)) {
     325               0 :     return nsnull;
     326                 :   }
     327                 : 
     328              76 :   return request.forget();
     329                 : }
     330                 : 
     331                 : void
     332             142 : IDBOpenDBRequest::SetTransaction(IDBTransaction* aTransaction)
     333                 : {
     334             142 :   mTransaction = aTransaction;
     335             142 : }
     336                 : 
     337                 : void
     338              75 : IDBOpenDBRequest::RootResultValInternal()
     339                 : {
     340              75 :   NS_HOLD_JS_OBJECTS(this, IDBOpenDBRequest);
     341              75 : }
     342                 : 
     343                 : void
     344              75 : IDBOpenDBRequest::UnrootResultValInternal()
     345                 : {
     346              75 :   NS_DROP_JS_OBJECTS(this, IDBOpenDBRequest);
     347              75 : }
     348                 : 
     349            1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(IDBOpenDBRequest)
     350                 : 
     351               4 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBOpenDBRequest,
     352                 :                                                   IDBRequest)
     353               4 :   NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(upgradeneeded)
     354               4 :   NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(blocked)
     355               4 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     356                 : 
     357               4 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBOpenDBRequest,
     358                 :                                                 IDBRequest)
     359               4 :   NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(upgradeneeded)
     360               4 :   NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(blocked)
     361               4 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     362                 : 
     363            6606 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBOpenDBRequest)
     364            4122 :   NS_INTERFACE_MAP_ENTRY(nsIIDBOpenDBRequest)
     365            3893 :   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBOpenDBRequest)
     366            3817 : NS_INTERFACE_MAP_END_INHERITING(IDBRequest)
     367                 : 
     368            4416 : NS_IMPL_ADDREF_INHERITED(IDBOpenDBRequest, IDBRequest)
     369            4416 : NS_IMPL_RELEASE_INHERITED(IDBOpenDBRequest, IDBRequest)
     370                 : 
     371                 : DOMCI_DATA(IDBOpenDBRequest, IDBOpenDBRequest)
     372                 : 
     373               4 : NS_IMPL_EVENT_HANDLER(IDBOpenDBRequest, blocked);
     374            4465 : NS_IMPL_EVENT_HANDLER(IDBOpenDBRequest, upgradeneeded);

Generated by: LCOV version 1.7