ActorsChild.cpp (6177B)
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 "ActorsChild.h" 8 9 // Local includes 10 #include "SDBConnection.h" 11 #include "SDBRequest.h" 12 #include "SDBResults.h" 13 14 // Global includes 15 #include "mozilla/Assertions.h" 16 #include "mozilla/dom/PBackgroundSDBRequest.h" 17 #include "nsError.h" 18 #include "nsID.h" 19 #include "nsISDBResults.h" 20 #include "nsVariant.h" 21 22 namespace mozilla::dom { 23 24 /******************************************************************************* 25 * SDBConnectionChild 26 ******************************************************************************/ 27 28 SDBConnectionChild::SDBConnectionChild(SDBConnection* aConnection) 29 : mConnection(aConnection) { 30 AssertIsOnOwningThread(); 31 MOZ_ASSERT(aConnection); 32 33 MOZ_COUNT_CTOR(SDBConnectionChild); 34 } 35 36 SDBConnectionChild::~SDBConnectionChild() { 37 AssertIsOnOwningThread(); 38 39 MOZ_COUNT_DTOR(SDBConnectionChild); 40 } 41 42 void SDBConnectionChild::SendDeleteMeInternal() { 43 AssertIsOnOwningThread(); 44 45 if (mConnection) { 46 mConnection->ClearBackgroundActor(); 47 mConnection = nullptr; 48 49 MOZ_ALWAYS_TRUE(PBackgroundSDBConnectionChild::SendDeleteMe()); 50 } 51 } 52 53 void SDBConnectionChild::ActorDestroy(ActorDestroyReason aWhy) { 54 AssertIsOnOwningThread(); 55 56 if (mConnection) { 57 mConnection->ClearBackgroundActor(); 58 #ifdef DEBUG 59 mConnection = nullptr; 60 #endif 61 } 62 } 63 64 PBackgroundSDBRequestChild* SDBConnectionChild::AllocPBackgroundSDBRequestChild( 65 const SDBRequestParams& aParams) { 66 AssertIsOnOwningThread(); 67 68 MOZ_CRASH( 69 "PBackgroundSDBRequestChild actors should be manually " 70 "constructed!"); 71 } 72 73 bool SDBConnectionChild::DeallocPBackgroundSDBRequestChild( 74 PBackgroundSDBRequestChild* aActor) { 75 AssertIsOnOwningThread(); 76 MOZ_ASSERT(aActor); 77 78 delete static_cast<SDBRequestChild*>(aActor); 79 return true; 80 } 81 82 mozilla::ipc::IPCResult SDBConnectionChild::RecvAllowToClose() { 83 AssertIsOnOwningThread(); 84 85 if (mConnection) { 86 mConnection->AllowToClose(); 87 } 88 89 return IPC_OK(); 90 } 91 92 mozilla::ipc::IPCResult SDBConnectionChild::RecvClosed() { 93 AssertIsOnOwningThread(); 94 95 if (mConnection) { 96 mConnection->OnClose(/* aAbnormal */ true); 97 } 98 99 return IPC_OK(); 100 } 101 102 /******************************************************************************* 103 * SDBRequestChild 104 ******************************************************************************/ 105 106 SDBRequestChild::SDBRequestChild(SDBRequest* aRequest) 107 : mConnection(aRequest->GetConnection()), mRequest(aRequest) { 108 AssertIsOnOwningThread(); 109 MOZ_ASSERT(aRequest); 110 111 MOZ_COUNT_CTOR(SDBRequestChild); 112 } 113 114 SDBRequestChild::~SDBRequestChild() { 115 AssertIsOnOwningThread(); 116 117 MOZ_COUNT_DTOR(SDBRequestChild); 118 } 119 120 #ifdef DEBUG 121 122 void SDBRequestChild::AssertIsOnOwningThread() const { 123 MOZ_ASSERT(mRequest); 124 mRequest->AssertIsOnOwningThread(); 125 } 126 127 #endif // DEBUG 128 129 void SDBRequestChild::HandleResponse(nsresult aResponse) { 130 AssertIsOnOwningThread(); 131 MOZ_ASSERT(NS_FAILED(aResponse)); 132 MOZ_ASSERT(mRequest); 133 134 mRequest->SetError(aResponse); 135 } 136 137 void SDBRequestChild::HandleResponse() { 138 AssertIsOnOwningThread(); 139 MOZ_ASSERT(mRequest); 140 141 RefPtr<nsVariant> variant = new nsVariant(); 142 variant->SetAsVoid(); 143 144 mRequest->SetResult(variant); 145 } 146 147 void SDBRequestChild::HandleResponse(const nsCString& aResponse) { 148 AssertIsOnOwningThread(); 149 MOZ_ASSERT(mRequest); 150 151 RefPtr<SDBResult> result = new SDBResult(aResponse); 152 153 RefPtr<nsVariant> variant = new nsVariant(); 154 variant->SetAsInterface(NS_GET_IID(nsISDBResult), result); 155 156 mRequest->SetResult(variant); 157 } 158 159 void SDBRequestChild::ActorDestroy(ActorDestroyReason aWhy) { 160 AssertIsOnOwningThread(); 161 162 if (mConnection) { 163 mConnection->AssertIsOnOwningThread(); 164 165 mConnection->OnRequestFinished(); 166 #ifdef DEBUG 167 mConnection = nullptr; 168 #endif 169 } 170 } 171 172 mozilla::ipc::IPCResult SDBRequestChild::Recv__delete__( 173 const SDBRequestResponse& aResponse) { 174 AssertIsOnOwningThread(); 175 MOZ_ASSERT(mRequest); 176 MOZ_ASSERT(mConnection); 177 178 switch (aResponse.type()) { 179 case SDBRequestResponse::Tnsresult: 180 HandleResponse(aResponse.get_nsresult()); 181 break; 182 183 case SDBRequestResponse::TSDBRequestOpenResponse: 184 if (mConnection->IsAllowedToClose()) { 185 // If the connection is allowed to close already, then we shouldn't set 186 // a result here. Instead we set an abort error. 187 HandleResponse(NS_ERROR_ABORT); 188 } else { 189 HandleResponse(); 190 } 191 192 // SDBConnection::OnOpen (which sets the SDBConnection::mOpen flag) must 193 // be called even when we set an abort error above. The parent is about 194 // to send the Closed message to the child and that ends up calling 195 // SDBConnection::OnClose which expects the SDBConnection::mOpen flag to 196 // be set. It's ok if the SDBConnection::mOpen flag is set to true for 197 // a short time after erroring out the open request because if the method 198 // SDBConnection::IsAllowToClose returns true it means that the flag 199 // SDBConnection::mAllowedToClose is set to true and that prevents any 200 // other operation from starting and the SDBConnection is basically 201 // unusable. 202 mConnection->OnOpen(); 203 204 break; 205 206 case SDBRequestResponse::TSDBRequestSeekResponse: 207 HandleResponse(); 208 break; 209 210 case SDBRequestResponse::TSDBRequestReadResponse: 211 HandleResponse(aResponse.get_SDBRequestReadResponse().data()); 212 break; 213 214 case SDBRequestResponse::TSDBRequestWriteResponse: 215 HandleResponse(); 216 break; 217 218 case SDBRequestResponse::TSDBRequestCloseResponse: 219 HandleResponse(); 220 221 mConnection->OnClose(/* aAbnormal */ false); 222 223 break; 224 225 default: 226 MOZ_CRASH("Unknown response type!"); 227 } 228 229 mConnection->OnRequestFinished(); 230 231 // Null this out so that we don't try to call OnRequestFinished() again in 232 // ActorDestroy. 233 mConnection = nullptr; 234 235 return IPC_OK(); 236 } 237 238 } // namespace mozilla::dom