Chromium Code Reviews| Index: Source/modules/indexeddb/IDBRequest.cpp |
| diff --git a/Source/modules/indexeddb/IDBRequest.cpp b/Source/modules/indexeddb/IDBRequest.cpp |
| index 2ae60699bd64133d9f563c4c63d5426f798ef414..28c43f2d6c6ff8a4c0fc9a5bd698143466c65c80 100644 |
| --- a/Source/modules/indexeddb/IDBRequest.cpp |
| +++ b/Source/modules/indexeddb/IDBRequest.cpp |
| @@ -79,7 +79,6 @@ IDBRequest::IDBRequest(ScriptExecutionContext* context, PassRefPtr<IDBAny> sourc |
| , m_hasPendingActivity(true) |
| , m_cursorType(IndexedDB::CursorKeyAndValue) |
| , m_cursorDirection(IndexedDB::CursorNext) |
| - , m_cursorFinished(false) |
| , m_pendingCursor(0) |
| , m_didFireUpgradeNeededEvent(false) |
| , m_preventPropagation(false) |
| @@ -184,6 +183,7 @@ void IDBRequest::setPendingCursor(PassRefPtr<IDBCursor> cursor) |
| ASSERT(!m_pendingCursor); |
| ASSERT(cursor == getResultCursor()); |
| + m_hasPendingActivity = true; |
| m_pendingCursor = cursor; |
| m_result.clear(); |
| m_readyState = PENDING; |
| @@ -191,7 +191,7 @@ void IDBRequest::setPendingCursor(PassRefPtr<IDBCursor> cursor) |
| m_transaction->registerRequest(this); |
| } |
| -PassRefPtr<IDBCursor> IDBRequest::getResultCursor() |
| +IDBCursor* IDBRequest::getResultCursor() |
| { |
| if (!m_result) |
| return 0; |
| @@ -217,11 +217,18 @@ void IDBRequest::setResultCursor(PassRefPtr<IDBCursor> cursor, PassRefPtr<IDBKey |
| m_result = IDBAny::create(IDBCursorWithValue::fromCursor(cursor)); |
| } |
| -void IDBRequest::finishCursor() |
| +void IDBRequest::checkForReferenceCycle() |
|
alecflett
2013/09/06 17:56:35
It would be neat if there were some primitive arou
jsbell
2013/09/06 18:07:43
Yeah. But in the short term this is the only insta
|
| { |
| - m_cursorFinished = true; |
| - if (m_readyState != PENDING) |
| - m_hasPendingActivity = false; |
| + // If this request and its cursor have the only references |
| + // to each other, then explicitly break the cycle. |
| + IDBCursor* cursor = getResultCursor(); |
| + if (!cursor || cursor->request() != this) |
| + return; |
| + |
| + if (!hasOneRef() || !cursor->hasOneRef()) |
| + return; |
| + |
| + m_result.clear(); |
| } |
| bool IDBRequest::shouldEnqueueEvent() const |
| @@ -496,7 +503,7 @@ bool IDBRequest::dispatchEvent(PassRefPtr<Event> event) |
| if (cursorToNotify) |
| cursorToNotify->postSuccessHandlerCallback(); |
| - if (m_readyState == DONE && (!cursorToNotify || m_cursorFinished) && event->type() != eventNames().upgradeneededEvent) |
| + if (m_readyState == DONE && event->type() != eventNames().upgradeneededEvent) |
| m_hasPendingActivity = false; |
| return dontPreventDefault; |