Changeset 209069 in webkit
- Timestamp:
- Nov 29, 2016 8:05:17 AM (7 years ago)
- Location:
- trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r209068 r209069 1 2016-11-29 Brady Eidson <beidson@apple.com> 2 3 IndexedDB 2.0: Queue up completed requests in the client, handle them one by one. 4 https://bugs.webkit.org/show_bug.cgi?id=165000 5 6 Reviewed by Alex Christensen. 7 8 * storage/indexeddb/modern/resources/transaction-scheduler-6.js: This test had a bug which was masked by previously 9 synchronous behavior. Fix that bug! 10 1 11 2016-11-29 Zalan Bujtas <zalan@apple.com> 2 12 -
trunk/LayoutTests/storage/indexeddb/modern/resources/transaction-scheduler-6.js
r195380 r209069 4 4 indexedDBTest(prepareDatabase); 5 5 6 function log(msg) 7 { 8 debug(msg); 9 } 6 10 7 11 function done() … … 14 18 function prepareDatabase(event) 15 19 { 16 debug("Upgrade needed: Old version - " + event.oldVersion + " New version - " + event.newVersion);20 log("Upgrade needed: Old version - " + event.oldVersion + " New version - " + event.newVersion); 17 21 18 22 var versionTransaction = event.target.transaction; … … 22 26 23 27 request.onerror = function(event) { 24 debug("put FAILED - " + event);28 log("put FAILED - " + event); 25 29 done(); 26 30 } 27 31 28 32 versionTransaction.onabort = function(event) { 29 debug("versionchange transaction aborted");33 log("versionchange transaction aborted"); 30 34 done(); 31 35 } 32 36 33 37 versionTransaction.oncomplete = function(event) { 34 debug("versionchange transaction completed");38 log("versionchange transaction completed"); 35 39 continueTest(); 36 40 } 37 41 38 42 versionTransaction.onerror = function(event) { 39 debug("versionchange transaction error'ed - " + event);43 log("versionchange transaction error'ed - " + event); 40 44 done(); 41 45 } … … 52 56 53 57 request.onsuccess = function(event) { 54 debug("Write in readwrite transaction succeeded");58 log("Write in readwrite transaction succeeded"); 55 59 } 56 60 57 61 request.onerror = function(event) { 58 debug("Write in readwrite transaction unexpectedly failed");62 log("Write in readwrite transaction unexpectedly failed"); 59 63 done(); 60 64 } 61 65 62 66 transaction.onabort = function(event) { 63 debug("readwrite transaction expectedly aborted");67 log("readwrite transaction expectedly aborted"); 64 68 done(); 65 69 } 66 70 67 71 transaction.oncomplete = function(event) { 68 debug("readwrite transaction completed");72 log("readwrite transaction completed"); 69 73 done(); 70 74 } 71 75 72 76 transaction.onerror = function(event) { 73 debug("readwrite transaction error'ed - " + event);77 log("readwrite transaction error'ed - " + event); 74 78 done(); 75 79 } … … 85 89 request.onsuccess = function(event) { 86 90 if (isFirstTime) { 87 debug("Starting a readonly transaction");91 log("Starting a readonly transaction"); 88 92 numberOfOpenTransactions++; 89 93 } … … 96 100 97 101 request.onerror = function(event) { 98 debug("Unexpected request error - " + event);102 log("Unexpected request error - " + event); 99 103 done(); 100 104 } 101 105 102 106 transaction.onerror = function(event) { 103 debug("Unexpected transaction error - " + event);107 log("Unexpected transaction error - " + event); 104 108 done(); 105 109 } 106 110 107 111 transaction.onabort = function(event) { 108 --numberOfOpenTransactions; 109 debug("Unexpected transaction abort - " + event); 112 log("Unexpected transaction abort - " + event); 110 113 done(); 111 114 } 112 115 113 116 transaction.oncomplete = function(event) { 114 --numberOfOpenTransactions; 115 debug("readonly transaction completed"); 117 log("readonly transaction completed"); 116 118 } 117 119 } -
trunk/Source/WebCore/ChangeLog
r209068 r209069 1 2016-11-29 Brady Eidson <beidson@apple.com> 2 3 IndexedDB 2.0: Queue up completed requests in the client, handle them one by one. 4 https://bugs.webkit.org/show_bug.cgi?id=165000 5 6 Reviewed by Alex Christensen. 7 8 No new tests (Covered extensively by every existing test). 9 10 Currently when a TransactionOperation completes on the server, it immediately completes 11 itself on the client side, including scheduling an event dispatch if necessary. 12 13 This patch changes it so that "server completed operations" instead queue up in the 14 IDBTransaction and are "client-side completed" asynchronously, 1-by-1. 15 16 Currently this is a "no behavior change" because only one operation is ever sent to 17 the server at a time. 18 19 But that will change with https://webkit.org/b/164932 20 And this patch is a pre-requisite for that. 21 22 * Modules/indexeddb/IDBRequest.cpp: 23 (WebCore::IDBRequest::dispatchEvent): 24 (WebCore::IDBRequest::didOpenOrIterateCursor): 25 (WebCore::IDBRequest::completeRequestAndDispatchEvent): 26 (WebCore::IDBRequest::requestCompleted): Deleted. 27 * Modules/indexeddb/IDBRequest.h: 28 29 * Modules/indexeddb/IDBTransaction.cpp: 30 (WebCore::IDBTransaction::IDBTransaction): 31 (WebCore::IDBTransaction::internalAbort): 32 (WebCore::IDBTransaction::abortOnServerAndCancelRequests): 33 (WebCore::IDBTransaction::scheduleOperation): 34 (WebCore::IDBTransaction::schedulePendingOperationTimer): 35 (WebCore::IDBTransaction::pendingOperationTimerFired): 36 (WebCore::IDBTransaction::operationCompletedOnServer): 37 (WebCore::IDBTransaction::scheduleCompletedOperationTimer): 38 (WebCore::IDBTransaction::completedOperationTimerFired): 39 (WebCore::IDBTransaction::completeNoncursorRequest): 40 (WebCore::IDBTransaction::completeCursorRequest): 41 (WebCore::IDBTransaction::finishedDispatchEventForRequest): 42 (WebCore::IDBTransaction::didStart): 43 (WebCore::IDBTransaction::didOpenCursorOnServer): 44 (WebCore::IDBTransaction::didIterateCursorOnServer): 45 (WebCore::IDBTransaction::didGetAllRecordsOnServer): 46 (WebCore::IDBTransaction::didGetRecordOnServer): 47 (WebCore::IDBTransaction::didGetCountOnServer): 48 (WebCore::IDBTransaction::didDeleteRecordOnServer): 49 (WebCore::IDBTransaction::didClearObjectStoreOnServer): 50 (WebCore::IDBTransaction::putOrAddOnServer): 51 (WebCore::IDBTransaction::didPutOrAddOnServer): 52 (WebCore::IDBTransaction::operationCompletedOnClient): 53 (WebCore::IDBTransaction::deactivate): 54 (WebCore::IDBTransaction::connectionClosedFromServer): 55 (WebCore::IDBTransaction::scheduleOperationTimer): Deleted. 56 (WebCore::IDBTransaction::operationTimerFired): Deleted. 57 (WebCore::IDBTransaction::operationDidComplete): Deleted. 58 * Modules/indexeddb/IDBTransaction.h: 59 60 * Modules/indexeddb/client/IDBConnectionProxy.cpp: 61 (WebCore::IDBClient::IDBConnectionProxy::completeOperation): 62 63 * Modules/indexeddb/client/TransactionOperation.cpp: 64 (WebCore::IDBClient::TransactionOperation::TransactionOperation): 65 * Modules/indexeddb/client/TransactionOperation.h: 66 (WebCore::IDBClient::TransactionOperation::transitionToCompleteOnThisThread): 67 (WebCore::IDBClient::TransactionOperation::transitionToComplete): 68 (WebCore::IDBClient::TransactionOperation::doComplete): 69 (WebCore::IDBClient::TransactionOperation::idbRequest): 70 (WebCore::IDBClient::TransactionOperation::performCompleteOnOriginThread): Deleted. 71 (WebCore::IDBClient::TransactionOperation::completed): Deleted. 72 1 73 2016-11-29 Zalan Bujtas <zalan@apple.com> 2 74 -
trunk/Source/WebCore/Modules/indexeddb/IDBRequest.cpp
r208306 r209069 305 305 } 306 306 307 if (m_transaction) 308 m_transaction->finishedDispatchEventForRequest(*this); 309 307 310 return dontPreventDefault; 308 311 } … … 466 469 m_pendingCursor = nullptr; 467 470 468 requestCompleted(resultData);469 } 470 471 void IDBRequest:: requestCompleted(const IDBResultData& resultData)471 completeRequestAndDispatchEvent(resultData); 472 } 473 474 void IDBRequest::completeRequestAndDispatchEvent(const IDBResultData& resultData) 472 475 { 473 476 ASSERT(currentThread() == originThreadID()); -
trunk/Source/WebCore/Modules/indexeddb/IDBRequest.h
r208476 r209069 88 88 using RefCounted::deref; 89 89 90 void requestCompleted(const IDBResultData&);90 void completeRequestAndDispatchEvent(const IDBResultData&); 91 91 92 92 void setResult(const IDBKeyData&); -
trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp
r208985 r209069 75 75 , m_database(database) 76 76 , m_info(info) 77 , m_operationTimer(*this, &IDBTransaction::operationTimerFired) 77 , m_pendingOperationTimer(*this, &IDBTransaction::pendingOperationTimerFired) 78 , m_completedOperationTimer(*this, &IDBTransaction::completedOperationTimerFired) 78 79 , m_openDBRequest(request) 80 , m_currentlyCompletingRequest(request) 79 81 80 82 { … … 245 247 transitionedToFinishing(IndexedDB::TransactionState::Aborting); 246 248 247 m_abortQueue.swap(m_ transactionOperationQueue);249 m_abortQueue.swap(m_pendingTransactionOperationQueue); 248 250 249 251 scheduleOperation(IDBClient::createTransactionOperation(*this, nullptr, &IDBTransaction::abortOnServerAndCancelRequests)); … … 254 256 LOG(IndexedDB, "IDBTransaction::abortOnServerAndCancelRequests"); 255 257 ASSERT(currentThread() == m_database->originThreadID()); 256 ASSERT(m_ transactionOperationQueue.isEmpty());258 ASSERT(m_pendingTransactionOperationQueue.isEmpty()); 257 259 258 260 m_database->connectionProxy().abortTransaction(*this); … … 261 263 m_transactionOperationMap.remove(operation.identifier()); 262 264 265 m_currentlyCompletingRequest = nullptr; 266 263 267 IDBError error(IDBDatabaseException::AbortError); 264 for (auto& operation : m_abortQueue) 265 operation->completed(IDBResultData::error(operation->identifier(), error)); 268 for (auto& operation : m_abortQueue) { 269 m_currentlyCompletingRequest = nullptr; 270 operation->doComplete(IDBResultData::error(operation->identifier(), error)); 271 } 266 272 267 273 // Since we're aborting, it should be impossible to have queued any further operations. 268 ASSERT(m_ transactionOperationQueue.isEmpty());274 ASSERT(m_pendingTransactionOperationQueue.isEmpty()); 269 275 } 270 276 … … 340 346 ASSERT(currentThread() == m_database->originThreadID()); 341 347 342 m_ transactionOperationQueue.append(operation);348 m_pendingTransactionOperationQueue.append(operation); 343 349 m_transactionOperationMap.set(operation->identifier(), WTFMove(operation)); 344 350 345 schedule OperationTimer();346 } 347 348 void IDBTransaction::schedule OperationTimer()349 { 350 ASSERT(currentThread() == m_database->originThreadID()); 351 352 if (!m_ operationTimer.isActive())353 m_ operationTimer.startOneShot(0);354 } 355 356 void IDBTransaction:: operationTimerFired()357 { 358 LOG(IndexedDB, "IDBTransaction:: operationTimerFired (%p)", this);351 schedulePendingOperationTimer(); 352 } 353 354 void IDBTransaction::schedulePendingOperationTimer() 355 { 356 ASSERT(currentThread() == m_database->originThreadID()); 357 358 if (!m_pendingOperationTimer.isActive()) 359 m_pendingOperationTimer.startOneShot(0); 360 } 361 362 void IDBTransaction::pendingOperationTimerFired() 363 { 364 LOG(IndexedDB, "IDBTransaction::pendingOperationTimerFired (%p)", this); 359 365 ASSERT(currentThread() == m_database->originThreadID()); 360 366 … … 362 368 return; 363 369 364 if (!m_ transactionOperationQueue.isEmpty()) {365 auto operation = m_ transactionOperationQueue.takeFirst();370 if (!m_pendingTransactionOperationQueue.isEmpty()) { 371 auto operation = m_pendingTransactionOperationQueue.takeFirst(); 366 372 operation->perform(); 367 373 … … 374 380 if (!isFinishedOrFinishing()) 375 381 commit(); 382 } 383 384 void IDBTransaction::operationCompletedOnServer(const IDBResultData& data, IDBClient::TransactionOperation& operation) 385 { 386 ASSERT(currentThread() == m_database->originThreadID()); 387 ASSERT(currentThread() == operation.originThreadID()); 388 389 m_completedOnServerQueue.append({ &operation, data }); 390 scheduleCompletedOperationTimer(); 391 } 392 393 void IDBTransaction::scheduleCompletedOperationTimer() 394 { 395 ASSERT(currentThread() == m_database->originThreadID()); 396 397 if (!m_completedOperationTimer.isActive()) 398 m_completedOperationTimer.startOneShot(0); 399 } 400 401 void IDBTransaction::completedOperationTimerFired() 402 { 403 LOG(IndexedDB, "IDBTransaction::completedOperationTimerFired (%p)", this); 404 ASSERT(currentThread() == m_database->originThreadID()); 405 406 if (m_completedOnServerQueue.isEmpty() || m_currentlyCompletingRequest) 407 return; 408 409 auto iterator = m_completedOnServerQueue.takeFirst(); 410 iterator.first->doComplete(iterator.second); 411 412 if (!m_completedOnServerQueue.isEmpty() && !m_currentlyCompletingRequest) 413 scheduleCompletedOperationTimer(); 414 } 415 416 void IDBTransaction::completeNoncursorRequest(IDBRequest& request, const IDBResultData& result) 417 { 418 ASSERT(!m_currentlyCompletingRequest); 419 420 request.completeRequestAndDispatchEvent(result); 421 422 m_currentlyCompletingRequest = &request; 423 } 424 425 void IDBTransaction::completeCursorRequest(IDBRequest& request, const IDBResultData& result) 426 { 427 ASSERT(!m_currentlyCompletingRequest); 428 429 request.didOpenOrIterateCursor(result); 430 431 m_currentlyCompletingRequest = &request; 432 } 433 434 void IDBTransaction::finishedDispatchEventForRequest(IDBRequest& request) 435 { 436 if (isFinishedOrFinishing()) 437 return; 438 439 ASSERT_UNUSED(request, !m_currentlyCompletingRequest || m_currentlyCompletingRequest == &request); 440 441 m_currentlyCompletingRequest = nullptr; 442 scheduleCompletedOperationTimer(); 376 443 } 377 444 … … 423 490 } 424 491 425 schedule OperationTimer();492 schedulePendingOperationTimer(); 426 493 } 427 494 … … 725 792 ASSERT(currentThread() == m_database->originThreadID()); 726 793 727 request.didOpenOrIterateCursor(resultData);794 completeCursorRequest(request, resultData); 728 795 } 729 796 … … 754 821 ASSERT(currentThread() == m_database->originThreadID()); 755 822 756 request.didOpenOrIterateCursor(resultData);823 completeCursorRequest(request, resultData); 757 824 } 758 825 … … 807 874 808 875 if (resultData.type() == IDBResultType::Error) { 809 request.requestCompleted(resultData);876 completeNoncursorRequest(request, resultData); 810 877 return; 811 878 } … … 823 890 } 824 891 825 request.requestCompleted(resultData);892 completeNoncursorRequest(request, resultData); 826 893 } 827 894 … … 891 958 892 959 if (resultData.type() == IDBResultType::Error) { 893 request.requestCompleted(resultData);960 completeNoncursorRequest(request, resultData); 894 961 return; 895 962 } … … 911 978 } 912 979 913 request.requestCompleted(resultData);980 completeNoncursorRequest(request, resultData); 914 981 } 915 982 … … 962 1029 963 1030 request.setResult(resultData.resultInteger()); 964 request.requestCompleted(resultData);1031 completeNoncursorRequest(request, resultData); 965 1032 } 966 1033 … … 995 1062 996 1063 request.setResultToUndefined(); 997 request.requestCompleted(resultData);1064 completeNoncursorRequest(request, resultData); 998 1065 } 999 1066 … … 1029 1096 1030 1097 request.setResultToUndefined(); 1031 request.requestCompleted(resultData);1098 completeNoncursorRequest(request, resultData); 1032 1099 } 1033 1100 … … 1075 1142 auto result = IDBResultData::error(operation.identifier(), { IDBDatabaseException::UnknownError, ASCIILiteral("Error preparing Blob/File data to be stored in object store") }); 1076 1143 scriptExecutionContext()->postTask([protectedOperation = WTFMove(protectedOperation), result = WTFMove(result)](ScriptExecutionContext&) { 1077 protectedOperation-> completed(result);1144 protectedOperation->doComplete(result); 1078 1145 }); 1079 1146 } … … 1093 1160 auto result = IDBResultData::error(protectedOperation->identifier(), { IDBDatabaseException::UnknownError, ASCIILiteral("Error preparing Blob/File data to be stored in object store") }); 1094 1161 callOnMainThread([protectedThis = WTFMove(protectedThis), protectedOperation = WTFMove(protectedOperation), result = WTFMove(result)]() mutable { 1095 protectedOperation-> completed(result);1162 protectedOperation->doComplete(result); 1096 1163 }); 1097 1164 }); … … 1107 1174 else 1108 1175 request.setResultToUndefined(); 1109 request.requestCompleted(resultData);1176 completeNoncursorRequest(request, resultData); 1110 1177 } 1111 1178 … … 1168 1235 } 1169 1236 1170 void IDBTransaction::operationDidComplete(IDBClient::TransactionOperation& operation) 1171 { 1237 void IDBTransaction::operationCompletedOnClient(IDBClient::TransactionOperation& operation) 1238 { 1239 LOG(IndexedDB, "IDBTransaction::operationCompletedOnClient"); 1240 1172 1241 ASSERT(m_transactionOperationMap.get(operation.identifier()) == &operation); 1173 1242 ASSERT(currentThread() == m_database->originThreadID()); … … 1176 1245 m_transactionOperationMap.remove(operation.identifier()); 1177 1246 1178 schedule OperationTimer();1247 schedulePendingOperationTimer(); 1179 1248 } 1180 1249 … … 1204 1273 m_state = IndexedDB::TransactionState::Inactive; 1205 1274 1206 schedule OperationTimer();1275 schedulePendingOperationTimer(); 1207 1276 } 1208 1277 … … 1216 1285 copyValuesToVector(m_transactionOperationMap, operations); 1217 1286 1218 for (auto& operation : operations) 1219 operation->completed(IDBResultData::error(operation->identifier(), error)); 1287 for (auto& operation : operations) { 1288 m_currentlyCompletingRequest = nullptr; 1289 operation->doComplete(IDBResultData::error(operation->identifier(), error)); 1290 } 1220 1291 1221 1292 connectionProxy().forgetActiveOperations(operations); 1222 1293 1223 m_ transactionOperationQueue.clear();1294 m_pendingTransactionOperationQueue.clear(); 1224 1295 m_abortQueue.clear(); 1225 1296 m_transactionOperationMap.clear(); -
trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.h
r208985 r209069 139 139 void deactivate(); 140 140 141 void operationDidComplete(IDBClient::TransactionOperation&); 141 void operationCompletedOnServer(const IDBResultData&, IDBClient::TransactionOperation&); 142 void operationCompletedOnClient(IDBClient::TransactionOperation&); 143 144 void finishedDispatchEventForRequest(IDBRequest&); 142 145 143 146 bool isFinishedOrFinishing() const; … … 160 163 161 164 void scheduleOperation(RefPtr<IDBClient::TransactionOperation>&&); 162 void operationTimerFired(); 165 void pendingOperationTimerFired(); 166 void completedOperationTimerFired(); 163 167 164 168 void fireOnComplete(); … … 218 222 void establishOnServer(); 219 223 220 void scheduleOperationTimer(); 224 void completeNoncursorRequest(IDBRequest&, const IDBResultData&); 225 void completeCursorRequest(IDBRequest&, const IDBResultData&); 226 227 void schedulePendingOperationTimer(); 228 void scheduleCompletedOperationTimer(); 221 229 222 230 Ref<IDBDatabase> m_database; … … 229 237 RefPtr<DOMError> m_domError; 230 238 231 Timer m_operationTimer; 239 Timer m_pendingOperationTimer; 240 Timer m_completedOperationTimer; 232 241 std::unique_ptr<Timer> m_activationTimer; 233 242 234 243 RefPtr<IDBOpenDBRequest> m_openDBRequest; 235 244 236 Deque<RefPtr<IDBClient::TransactionOperation>> m_transactionOperationQueue; 245 Deque<RefPtr<IDBClient::TransactionOperation>> m_pendingTransactionOperationQueue; 246 Deque<std::pair<RefPtr<IDBClient::TransactionOperation>, IDBResultData>> m_completedOnServerQueue; 237 247 Deque<RefPtr<IDBClient::TransactionOperation>> m_abortQueue; 238 248 HashMap<IDBResourceIdentifier, RefPtr<IDBClient::TransactionOperation>> m_transactionOperationMap; … … 243 253 244 254 HashSet<RefPtr<IDBRequest>> m_openRequests; 255 RefPtr<IDBRequest> m_currentlyCompletingRequest; 245 256 246 257 bool m_contextStopped { false }; -
trunk/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.cpp
r208609 r209069 250 250 return; 251 251 252 operation-> performCompleteOnOriginThread(resultData, WTFMove(operation));252 operation->transitionToComplete(resultData, WTFMove(operation)); 253 253 } 254 254 -
trunk/Source/WebCore/Modules/indexeddb/client/TransactionOperation.cpp
r205462 r209069 44 44 if (auto* cursor = request.pendingCursor()) 45 45 m_cursorIdentifier = std::make_unique<IDBResourceIdentifier>(cursor->info().identifier()); 46 47 m_idbRequest = &request; 46 48 } 47 49 -
trunk/Source/WebCore/Modules/indexeddb/client/TransactionOperation.h
r208646 r209069 62 62 } 63 63 64 void performCompleteOnOriginThread(const IDBResultData& data, RefPtr<TransactionOperation>&& lastRef) 64 void transitionToCompleteOnThisThread(const IDBResultData& data) 65 { 66 ASSERT(m_originThreadID == currentThread()); 67 m_transaction->operationCompletedOnServer(data, *this); 68 } 69 70 void transitionToComplete(const IDBResultData& data, RefPtr<TransactionOperation>&& lastRef) 65 71 { 66 72 ASSERT(isMainThread()); 67 73 68 74 if (m_originThreadID == currentThread()) 69 completed(data);75 transitionToCompleteOnThisThread(data); 70 76 else { 71 m_transaction->performCallbackOnOriginThread(*this, &TransactionOperation:: completed, data);77 m_transaction->performCallbackOnOriginThread(*this, &TransactionOperation::transitionToCompleteOnThisThread, data); 72 78 m_transaction->callFunctionOnOriginThread([lastRef = WTFMove(lastRef)]() { 73 79 }); … … 75 81 } 76 82 77 void completed(const IDBResultData& data)83 void doComplete(const IDBResultData& data) 78 84 { 79 85 ASSERT(m_originThreadID == currentThread()); 80 86 ASSERT(m_completeFunction); 81 87 m_completeFunction(data); 82 m_transaction->operation DidComplete(*this);88 m_transaction->operationCompletedOnClient(*this); 83 89 84 90 // m_completeFunction might be holding the last ref to this TransactionOperation, … … 91 97 92 98 ThreadIdentifier originThreadID() const { return m_originThreadID; } 99 100 IDBRequest* idbRequest() { return m_idbRequest.get(); } 93 101 94 102 protected: … … 119 127 120 128 ThreadIdentifier m_originThreadID { currentThread() }; 129 RefPtr<IDBRequest> m_idbRequest; 121 130 }; 122 131 -
trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp
r208985 r209069 808 808 } 809 809 810 811 if (transaction->mode() == IDBTransactionMode::Versionchange) { 812 ASSERT(m_originalDatabaseInfoBeforeVersionChange); 810 if (transaction->mode() == IDBTransactionMode::Versionchange && m_originalDatabaseInfoBeforeVersionChange) 813 811 m_databaseInfo = WTFMove(m_originalDatabaseInfoBeforeVersionChange); 814 }815 812 816 813 return transaction->abort();
Note: See TracChangeset
for help on using the changeset viewer.