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 "SDBRequest.h"
8 
9 // Local includes
10 #include "SDBConnection.h"
11 
12 // Global includes
13 #include <utility>
14 #include "mozilla/MacroForEach.h"
15 #include "nsError.h"
16 #include "nsISDBCallbacks.h"
17 #include "nsISupportsUtils.h"
18 #include "nsIVariant.h"
19 #include "nsThreadUtils.h"
20 #include "nscore.h"
21 
22 namespace mozilla::dom {
23 
SDBRequest(SDBConnection * aConnection)24 SDBRequest::SDBRequest(SDBConnection* aConnection)
25     : mConnection(aConnection),
26       mResultCode(NS_OK),
27       mHaveResultOrErrorCode(false) {
28   AssertIsOnOwningThread();
29   MOZ_ASSERT(aConnection);
30 }
31 
~SDBRequest()32 SDBRequest::~SDBRequest() { AssertIsOnOwningThread(); }
33 
SetResult(nsIVariant * aResult)34 void SDBRequest::SetResult(nsIVariant* aResult) {
35   AssertIsOnOwningThread();
36   MOZ_ASSERT(aResult);
37   MOZ_ASSERT(mConnection);
38   MOZ_ASSERT(!mHaveResultOrErrorCode);
39 
40   mResult = aResult;
41   mHaveResultOrErrorCode = true;
42 
43   FireCallback();
44 }
45 
SetError(nsresult aRv)46 void SDBRequest::SetError(nsresult aRv) {
47   AssertIsOnOwningThread();
48   MOZ_ASSERT(mConnection);
49   MOZ_ASSERT(mResultCode == NS_OK);
50   MOZ_ASSERT(!mHaveResultOrErrorCode);
51 
52   mResultCode = aRv;
53   mHaveResultOrErrorCode = true;
54 
55   FireCallback();
56 }
57 
FireCallback()58 void SDBRequest::FireCallback() {
59   AssertIsOnOwningThread();
60 
61   if (mCallback) {
62     nsCOMPtr<nsISDBCallback> callback;
63     callback.swap(mCallback);
64 
65     MOZ_ALWAYS_SUCCEEDS(
66         NS_DispatchToCurrentThread(NewRunnableMethod<RefPtr<SDBRequest>>(
67             "nsISDBCallback::OnComplete", callback, &nsISDBCallback::OnComplete,
68             this)));
69   }
70 }
71 
72 NS_IMPL_CYCLE_COLLECTING_ADDREF(SDBRequest)
NS_IMPL_CYCLE_COLLECTING_RELEASE(SDBRequest)73 NS_IMPL_CYCLE_COLLECTING_RELEASE(SDBRequest)
74 
75 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SDBRequest)
76   NS_INTERFACE_MAP_ENTRY(nsISupports)
77   NS_INTERFACE_MAP_ENTRY(nsISDBRequest)
78 NS_INTERFACE_MAP_END
79 
80 NS_IMPL_CYCLE_COLLECTION(SDBRequest, mCallback, mResult)
81 
82 NS_IMETHODIMP
83 SDBRequest::GetResult(nsIVariant** aResult) {
84   AssertIsOnOwningThread();
85   MOZ_ASSERT(aResult);
86 
87   if (!mHaveResultOrErrorCode) {
88     return NS_ERROR_NOT_AVAILABLE;
89   }
90 
91   NS_IF_ADDREF(*aResult = mResult);
92   return NS_OK;
93 }
94 
95 NS_IMETHODIMP
GetResultCode(nsresult * aResultCode)96 SDBRequest::GetResultCode(nsresult* aResultCode) {
97   AssertIsOnOwningThread();
98   MOZ_ASSERT(aResultCode);
99 
100   if (!mHaveResultOrErrorCode) {
101     return NS_ERROR_NOT_AVAILABLE;
102   }
103 
104   *aResultCode = mResultCode;
105   return NS_OK;
106 }
107 
108 NS_IMETHODIMP
GetCallback(nsISDBCallback ** aCallback)109 SDBRequest::GetCallback(nsISDBCallback** aCallback) {
110   AssertIsOnOwningThread();
111   MOZ_ASSERT(aCallback);
112 
113   NS_IF_ADDREF(*aCallback = mCallback);
114   return NS_OK;
115 }
116 
117 NS_IMETHODIMP
SetCallback(nsISDBCallback * aCallback)118 SDBRequest::SetCallback(nsISDBCallback* aCallback) {
119   AssertIsOnOwningThread();
120 
121   mCallback = aCallback;
122   return NS_OK;
123 }
124 
125 }  // namespace mozilla::dom
126