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 |