| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 m_state(Inactive), | 136 m_state(Inactive), |
| 137 m_oldDatabaseMetadata(oldMetadata) { | 137 m_oldDatabaseMetadata(oldMetadata) { |
| 138 DCHECK(m_database); | 138 DCHECK(m_database); |
| 139 DCHECK(m_openDBRequest); | 139 DCHECK(m_openDBRequest); |
| 140 DCHECK(m_scope.isEmpty()); | 140 DCHECK(m_scope.isEmpty()); |
| 141 | 141 |
| 142 m_database->transactionCreated(this); | 142 m_database->transactionCreated(this); |
| 143 } | 143 } |
| 144 | 144 |
| 145 IDBTransaction::~IDBTransaction() { | 145 IDBTransaction::~IDBTransaction() { |
| 146 DCHECK(m_state == Finished || m_contextStopped); | 146 DCHECK(m_state == Finished || !getExecutionContext()); |
| 147 DCHECK(m_requestList.isEmpty() || m_contextStopped); | 147 DCHECK(m_requestList.isEmpty() || !getExecutionContext()); |
| 148 } | 148 } |
| 149 | 149 |
| 150 DEFINE_TRACE(IDBTransaction) { | 150 DEFINE_TRACE(IDBTransaction) { |
| 151 visitor->trace(m_database); | 151 visitor->trace(m_database); |
| 152 visitor->trace(m_openDBRequest); | 152 visitor->trace(m_openDBRequest); |
| 153 visitor->trace(m_error); | 153 visitor->trace(m_error); |
| 154 visitor->trace(m_requestList); | 154 visitor->trace(m_requestList); |
| 155 visitor->trace(m_objectStoreMap); | 155 visitor->trace(m_objectStoreMap); |
| 156 visitor->trace(m_oldStoreMetadata); | 156 visitor->trace(m_oldStoreMetadata); |
| 157 visitor->trace(m_deletedIndexes); | 157 visitor->trace(m_deletedIndexes); |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 | 330 |
| 331 void IDBTransaction::abort(ExceptionState& exceptionState) { | 331 void IDBTransaction::abort(ExceptionState& exceptionState) { |
| 332 if (m_state == Finishing || m_state == Finished) { | 332 if (m_state == Finishing || m_state == Finished) { |
| 333 exceptionState.throwDOMException( | 333 exceptionState.throwDOMException( |
| 334 InvalidStateError, IDBDatabase::transactionFinishedErrorMessage); | 334 InvalidStateError, IDBDatabase::transactionFinishedErrorMessage); |
| 335 return; | 335 return; |
| 336 } | 336 } |
| 337 | 337 |
| 338 m_state = Finishing; | 338 m_state = Finishing; |
| 339 | 339 |
| 340 if (m_contextStopped) | 340 if (!getExecutionContext()) |
| 341 return; | 341 return; |
| 342 | 342 |
| 343 abortOutstandingRequests(); | 343 abortOutstandingRequests(); |
| 344 revertDatabaseMetadata(); | 344 revertDatabaseMetadata(); |
| 345 | 345 |
| 346 if (backendDB()) | 346 if (backendDB()) |
| 347 backendDB()->abort(m_id); | 347 backendDB()->abort(m_id); |
| 348 } | 348 } |
| 349 | 349 |
| 350 void IDBTransaction::registerRequest(IDBRequest* request) { | 350 void IDBTransaction::registerRequest(IDBRequest* request) { |
| 351 DCHECK(request); | 351 DCHECK(request); |
| 352 DCHECK_EQ(m_state, Active); | 352 DCHECK_EQ(m_state, Active); |
| 353 m_requestList.add(request); | 353 m_requestList.add(request); |
| 354 } | 354 } |
| 355 | 355 |
| 356 void IDBTransaction::unregisterRequest(IDBRequest* request) { | 356 void IDBTransaction::unregisterRequest(IDBRequest* request) { |
| 357 DCHECK(request); | 357 DCHECK(request); |
| 358 // If we aborted the request, it will already have been removed. | 358 // If we aborted the request, it will already have been removed. |
| 359 m_requestList.remove(request); | 359 m_requestList.remove(request); |
| 360 } | 360 } |
| 361 | 361 |
| 362 void IDBTransaction::onAbort(DOMException* error) { | 362 void IDBTransaction::onAbort(DOMException* error) { |
| 363 IDB_TRACE("IDBTransaction::onAbort"); | 363 IDB_TRACE("IDBTransaction::onAbort"); |
| 364 if (m_contextStopped) { | 364 if (!getExecutionContext()) { |
| 365 finished(); | 365 finished(); |
| 366 return; | 366 return; |
| 367 } | 367 } |
| 368 | 368 |
| 369 DCHECK_NE(m_state, Finished); | 369 DCHECK_NE(m_state, Finished); |
| 370 if (m_state != Finishing) { | 370 if (m_state != Finishing) { |
| 371 // Abort was not triggered by front-end. | 371 // Abort was not triggered by front-end. |
| 372 DCHECK(error); | 372 DCHECK(error); |
| 373 setError(error); | 373 setError(error); |
| 374 | 374 |
| 375 abortOutstandingRequests(); | 375 abortOutstandingRequests(); |
| 376 revertDatabaseMetadata(); | 376 revertDatabaseMetadata(); |
| 377 | 377 |
| 378 m_state = Finishing; | 378 m_state = Finishing; |
| 379 } | 379 } |
| 380 | 380 |
| 381 if (isVersionChange()) | 381 if (isVersionChange()) |
| 382 m_database->close(); | 382 m_database->close(); |
| 383 | 383 |
| 384 // Enqueue events before notifying database, as database may close which | 384 // Enqueue events before notifying database, as database may close which |
| 385 // enqueues more events and order matters. | 385 // enqueues more events and order matters. |
| 386 enqueueEvent(Event::createBubble(EventTypeNames::abort)); | 386 enqueueEvent(Event::createBubble(EventTypeNames::abort)); |
| 387 finished(); | 387 finished(); |
| 388 } | 388 } |
| 389 | 389 |
| 390 void IDBTransaction::onComplete() { | 390 void IDBTransaction::onComplete() { |
| 391 IDB_TRACE("IDBTransaction::onComplete"); | 391 IDB_TRACE("IDBTransaction::onComplete"); |
| 392 if (m_contextStopped) { | 392 if (!getExecutionContext()) { |
| 393 finished(); | 393 finished(); |
| 394 return; | 394 return; |
| 395 } | 395 } |
| 396 | 396 |
| 397 DCHECK_NE(m_state, Finished); | 397 DCHECK_NE(m_state, Finished); |
| 398 m_state = Finishing; | 398 m_state = Finishing; |
| 399 | 399 |
| 400 // Enqueue events before notifying database, as database may close which | 400 // Enqueue events before notifying database, as database may close which |
| 401 // enqueues more events and order matters. | 401 // enqueues more events and order matters. |
| 402 enqueueEvent(Event::create(EventTypeNames::complete)); | 402 enqueueEvent(Event::create(EventTypeNames::complete)); |
| 403 finished(); | 403 finished(); |
| 404 } | 404 } |
| 405 | 405 |
| 406 bool IDBTransaction::hasPendingActivity() const { | 406 bool IDBTransaction::hasPendingActivity() const { |
| 407 // FIXME: In an ideal world, we should return true as long as anyone has a or | 407 // FIXME: In an ideal world, we should return true as long as anyone has a or |
| 408 // can get a handle to us or any child request object and any of those have | 408 // can get a handle to us or any child request object and any of those have |
| 409 // event listeners. This is in order to handle user generated events | 409 // event listeners. This is in order to handle user generated events |
| 410 // properly. | 410 // properly. |
| 411 return m_hasPendingActivity && !m_contextStopped; | 411 return m_hasPendingActivity && getExecutionContext(); |
| 412 } | 412 } |
| 413 | 413 |
| 414 WebIDBTransactionMode IDBTransaction::stringToMode(const String& modeString) { | 414 WebIDBTransactionMode IDBTransaction::stringToMode(const String& modeString) { |
| 415 if (modeString == IndexedDBNames::readonly) | 415 if (modeString == IndexedDBNames::readonly) |
| 416 return WebIDBTransactionModeReadOnly; | 416 return WebIDBTransactionModeReadOnly; |
| 417 if (modeString == IndexedDBNames::readwrite) | 417 if (modeString == IndexedDBNames::readwrite) |
| 418 return WebIDBTransactionModeReadWrite; | 418 return WebIDBTransactionModeReadWrite; |
| 419 if (modeString == IndexedDBNames::versionchange) | 419 if (modeString == IndexedDBNames::versionchange) |
| 420 return WebIDBTransactionModeVersionChange; | 420 return WebIDBTransactionModeVersionChange; |
| 421 NOTREACHED(); | 421 NOTREACHED(); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 const AtomicString& IDBTransaction::interfaceName() const { | 457 const AtomicString& IDBTransaction::interfaceName() const { |
| 458 return EventTargetNames::IDBTransaction; | 458 return EventTargetNames::IDBTransaction; |
| 459 } | 459 } |
| 460 | 460 |
| 461 ExecutionContext* IDBTransaction::getExecutionContext() const { | 461 ExecutionContext* IDBTransaction::getExecutionContext() const { |
| 462 return ActiveDOMObject::getExecutionContext(); | 462 return ActiveDOMObject::getExecutionContext(); |
| 463 } | 463 } |
| 464 | 464 |
| 465 DispatchEventResult IDBTransaction::dispatchEventInternal(Event* event) { | 465 DispatchEventResult IDBTransaction::dispatchEventInternal(Event* event) { |
| 466 IDB_TRACE("IDBTransaction::dispatchEvent"); | 466 IDB_TRACE("IDBTransaction::dispatchEvent"); |
| 467 if (m_contextStopped || !getExecutionContext()) { | 467 if (!getExecutionContext()) { |
| 468 m_state = Finished; | 468 m_state = Finished; |
| 469 return DispatchEventResult::CanceledBeforeDispatch; | 469 return DispatchEventResult::CanceledBeforeDispatch; |
| 470 } | 470 } |
| 471 DCHECK_NE(m_state, Finished); | 471 DCHECK_NE(m_state, Finished); |
| 472 DCHECK(m_hasPendingActivity); | 472 DCHECK(m_hasPendingActivity); |
| 473 DCHECK(getExecutionContext()); | 473 DCHECK(getExecutionContext()); |
| 474 DCHECK_EQ(event->target(), this); | 474 DCHECK_EQ(event->target(), this); |
| 475 m_state = Finished; | 475 m_state = Finished; |
| 476 | 476 |
| 477 HeapVector<Member<EventTarget>> targets; | 477 HeapVector<Member<EventTarget>> targets; |
| 478 targets.append(this); | 478 targets.append(this); |
| 479 targets.append(db()); | 479 targets.append(db()); |
| 480 | 480 |
| 481 // FIXME: When we allow custom event dispatching, this will probably need to | 481 // FIXME: When we allow custom event dispatching, this will probably need to |
| 482 // change. | 482 // change. |
| 483 DCHECK(event->type() == EventTypeNames::complete || | 483 DCHECK(event->type() == EventTypeNames::complete || |
| 484 event->type() == EventTypeNames::abort); | 484 event->type() == EventTypeNames::abort); |
| 485 DispatchEventResult dispatchResult = | 485 DispatchEventResult dispatchResult = |
| 486 IDBEventDispatcher::dispatch(event, targets); | 486 IDBEventDispatcher::dispatch(event, targets); |
| 487 // FIXME: Try to construct a test where |this| outlives openDBRequest and we | 487 // FIXME: Try to construct a test where |this| outlives openDBRequest and we |
| 488 // get a crash. | 488 // get a crash. |
| 489 if (m_openDBRequest) { | 489 if (m_openDBRequest) { |
| 490 DCHECK(isVersionChange()); | 490 DCHECK(isVersionChange()); |
| 491 m_openDBRequest->transactionDidFinishAndDispatch(); | 491 m_openDBRequest->transactionDidFinishAndDispatch(); |
| 492 } | 492 } |
| 493 m_hasPendingActivity = false; | 493 m_hasPendingActivity = false; |
| 494 return dispatchResult; | 494 return dispatchResult; |
| 495 } | 495 } |
| 496 | 496 |
| 497 void IDBTransaction::contextDestroyed() { | |
| 498 if (m_contextStopped) | |
| 499 return; | |
| 500 | |
| 501 m_contextStopped = true; | |
| 502 | |
| 503 abort(IGNORE_EXCEPTION); | |
| 504 } | |
| 505 | |
| 506 void IDBTransaction::enqueueEvent(Event* event) { | 497 void IDBTransaction::enqueueEvent(Event* event) { |
| 507 DCHECK_NE(m_state, Finished) | 498 DCHECK_NE(m_state, Finished) |
| 508 << "A finished transaction tried to enqueue an event of type " | 499 << "A finished transaction tried to enqueue an event of type " |
| 509 << event->type() << "."; | 500 << event->type() << "."; |
| 510 if (m_contextStopped || !getExecutionContext()) | 501 if (!getExecutionContext()) |
| 511 return; | 502 return; |
| 512 | 503 |
| 513 EventQueue* eventQueue = getExecutionContext()->getEventQueue(); | 504 EventQueue* eventQueue = getExecutionContext()->getEventQueue(); |
| 514 event->setTarget(this); | 505 event->setTarget(this); |
| 515 eventQueue->enqueueEvent(event); | 506 eventQueue->enqueueEvent(event); |
| 516 } | 507 } |
| 517 | 508 |
| 518 void IDBTransaction::abortOutstandingRequests() { | 509 void IDBTransaction::abortOutstandingRequests() { |
| 519 for (IDBRequest* request : m_requestList) | 510 for (IDBRequest* request : m_requestList) |
| 520 request->abort(); | 511 request->abort(); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 IDBObjectStore* objectStore = it.key; | 575 IDBObjectStore* objectStore = it.key; |
| 585 objectStore->clearIndexCache(); | 576 objectStore->clearIndexCache(); |
| 586 } | 577 } |
| 587 m_oldStoreMetadata.clear(); | 578 m_oldStoreMetadata.clear(); |
| 588 | 579 |
| 589 m_deletedIndexes.clear(); | 580 m_deletedIndexes.clear(); |
| 590 m_deletedObjectStores.clear(); | 581 m_deletedObjectStores.clear(); |
| 591 } | 582 } |
| 592 | 583 |
| 593 } // namespace blink | 584 } // namespace blink |
| OLD | NEW |