Changeset 122291 in webkit
- Timestamp:
- Jul 10, 2012 9:24:22 PM (12 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r122290 r122291 1 2012-07-10 Joshua Bell <jsbell@chromium.org> 2 3 IndexedDB: Ensure transaction abort events are deterministic in multiprocess ports 4 https://bugs.webkit.org/show_bug.cgi?id=90412 5 6 Reviewed by Tony Chang. 7 8 In multi-process ports (e.g. Chromium), transaction aborts triggered on the front-end could 9 be initiated while a "success" event was in-flight from the back end. This would lead to 10 apparently flaky behavior when requests would sometimes report success and sometimes report 11 an error. Address this by having front-end triggered aborts do the abort steps immediately, 12 then send the async abort request to the back end. 13 14 No new tests - behavior in single process ports (and DRT) covered by existing 15 tests. Will enable currently disabled Chromium tests to be enabled (crbug.com/83226). 16 17 * Modules/indexeddb/IDBRequest.cpp: 18 (WebCore::IDBRequest::IDBRequest): Initialize a new m_requestAborted flag, used to prevent 19 dispatching if an in-flight request comes in after the abort. 20 (WebCore::IDBRequest::abort): Set flag to prevent double dispatching. 21 (WebCore::IDBRequest::onError): Handle aborted-then-received-event case. 22 (WebCore::IDBRequest::onSuccess): Ditto. 23 (WebCore::IDBRequest::onSuccessWithContinuation): Ditto. 24 (WebCore::IDBRequest::dispatchEvent): On uncaught error, trigger abort on transaction front-end. 25 * Modules/indexeddb/IDBRequest.h: 26 (IDBRequest): 27 * Modules/indexeddb/IDBTransaction.cpp: 28 (WebCore::IDBTransaction::abort): Do abort steps locally first, then notify back-end. 29 (WebCore::IDBTransaction::onAbort): If abort wasn't triggered locally, clean up is still necessary. 30 1 31 2012-07-10 Julien Chaffraix <jchaffraix@webkit.org> 2 32 -
trunk/Source/WebCore/Modules/indexeddb/IDBRequest.cpp
r121612 r122291 58 58 , m_transaction(transaction) 59 59 , m_readyState(PENDING) 60 , m_requestAborted(false) 60 61 , m_requestFinished(false) 61 62 , m_cursorFinished(false) … … 167 168 void IDBRequest::abort() 168 169 { 170 ASSERT(!m_requestAborted); 169 171 if (m_contextStopped || !scriptExecutionContext()) 170 172 return; … … 187 189 m_result.clear(); 188 190 onError(IDBDatabaseError::create(IDBDatabaseException::IDB_ABORT_ERR, "The transaction was aborted, so the request cannot be fulfilled.")); 191 m_requestAborted = true; 189 192 } 190 193 … … 211 214 void IDBRequest::onError(PassRefPtr<IDBDatabaseError> error) 212 215 { 216 if (m_requestAborted) 217 return; 213 218 ASSERT(!m_errorCode && m_errorMessage.isNull() && !m_result); 214 219 m_errorCode = error->code(); … … 228 233 { 229 234 IDB_TRACE("IDBRequest::onSuccess(DOMStringList)"); 235 if (m_requestAborted) 236 return; 230 237 ASSERT(!m_errorCode && m_errorMessage.isNull() && !m_error && !m_result); 231 238 m_result = IDBAny::create(domStringList); … … 236 243 { 237 244 IDB_TRACE("IDBRequest::onSuccess(IDBCursor)"); 245 if (m_requestAborted) 246 return; 238 247 ASSERT(!m_errorCode && m_errorMessage.isNull() && !m_error && !m_result); 239 248 ASSERT(m_cursorType != IDBCursorBackendInterface::InvalidCursorType); … … 251 260 { 252 261 IDB_TRACE("IDBRequest::onSuccess(IDBDatabase)"); 262 if (m_requestAborted) 263 return; 253 264 ASSERT(!m_errorCode && m_errorMessage.isNull() && !m_error && !m_result); 254 265 if (m_contextStopped || !scriptExecutionContext()) … … 265 276 { 266 277 IDB_TRACE("IDBRequest::onSuccess(IDBKey)"); 278 if (m_requestAborted) 279 return; 267 280 ASSERT(!m_errorCode && m_errorMessage.isNull() && !m_error && !m_result); 268 281 if (idbKey && idbKey->isValid()) … … 276 289 { 277 290 IDB_TRACE("IDBRequest::onSuccess(IDBTransaction)"); 291 if (m_requestAborted) 292 return; 278 293 ASSERT(!m_errorCode && m_errorMessage.isNull() && !m_error && !m_result); 279 294 RefPtr<IDBTransactionBackendInterface> backend = prpBackend; … … 298 313 { 299 314 IDB_TRACE("IDBRequest::onSuccess(SerializedScriptValue)"); 315 if (m_requestAborted) 316 return; 300 317 ASSERT(!m_errorCode && m_errorMessage.isNull() && !m_error && !m_result); 301 318 m_result = IDBAny::create(serializedScriptValue); … … 308 325 { 309 326 LOG_ERROR("CHECKING: onSuccess(value, key, keypath)"); 327 if (m_requestAborted) 328 return; 310 329 RefPtr<SerializedScriptValue> serializedScriptValue = prpSerializedScriptValue; 311 330 #ifndef NDEBUG … … 322 341 { 323 342 IDB_TRACE("IDBRequest::onSuccessWithContinuation"); 343 if (m_requestAborted) 344 return; 324 345 ASSERT(!m_errorCode && m_errorMessage.isNull() && !m_error && !m_result); 325 346 ASSERT(m_cursor); … … 422 443 if (dontPreventDefault && event->type() == eventNames().errorEvent) { 423 444 m_transaction->setError(m_error); 424 m_transaction-> backend()->abort();445 m_transaction->abort(); 425 446 } 426 447 m_transaction->backend()->didCompleteTaskEvents(); -
trunk/Source/WebCore/Modules/indexeddb/IDBRequest.h
r121612 r122291 129 129 130 130 ReadyState m_readyState; 131 bool m_requestAborted; // May be aborted by transaction then receive async onsuccess; ignore vs. assert. 131 132 bool m_requestFinished; // Is it possible that we'll fire any more events? If not, we're finished. 132 133 bool m_cursorFinished; -
trunk/Source/WebCore/Modules/indexeddb/IDBTransaction.cpp
r122172 r122291 214 214 m_state = Finishing; 215 215 m_active = false; 216 217 while (!m_requestList.isEmpty()) { 218 IDBRequest* request = *m_requestList.begin(); 219 m_requestList.remove(request); 220 request->abort(); 221 } 222 216 223 RefPtr<IDBTransaction> selfRef = this; 217 224 if (m_backend) … … 268 275 { 269 276 ASSERT(m_state != Finished); 270 m_state = Finishing; 271 while (!m_requestList.isEmpty()) { 272 IDBRequest* request = *m_requestList.begin(); 273 m_requestList.remove(request); 274 request->abort(); 277 278 if (m_state != Finishing) { 279 // Abort was not triggered by front-end, so outstanding requests must 280 // be aborted now. 281 while (!m_requestList.isEmpty()) { 282 IDBRequest* request = *m_requestList.begin(); 283 m_requestList.remove(request); 284 request->abort(); 285 } 286 m_state = Finishing; 275 287 } 276 288
Note: See TracChangeset
for help on using the changeset viewer.