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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
72 , m_result(0) | 72 , m_result(0) |
73 , m_contextStopped(false) | 73 , m_contextStopped(false) |
74 , m_transaction(transaction) | 74 , m_transaction(transaction) |
75 , m_readyState(PENDING) | 75 , m_readyState(PENDING) |
76 , m_requestAborted(false) | 76 , m_requestAborted(false) |
77 , m_source(source) | 77 , m_source(source) |
78 , m_taskType(taskType) | 78 , m_taskType(taskType) |
79 , m_hasPendingActivity(true) | 79 , m_hasPendingActivity(true) |
80 , m_cursorType(IndexedDB::CursorKeyAndValue) | 80 , m_cursorType(IndexedDB::CursorKeyAndValue) |
81 , m_cursorDirection(IndexedDB::CursorNext) | 81 , m_cursorDirection(IndexedDB::CursorNext) |
82 , m_cursorFinished(false) | |
83 , m_pendingCursor(0) | 82 , m_pendingCursor(0) |
84 , m_didFireUpgradeNeededEvent(false) | 83 , m_didFireUpgradeNeededEvent(false) |
85 , m_preventPropagation(false) | 84 , m_preventPropagation(false) |
86 , m_requestState(context) | 85 , m_requestState(context) |
87 { | 86 { |
88 ScriptWrappable::init(this); | 87 ScriptWrappable::init(this); |
89 } | 88 } |
90 | 89 |
91 IDBRequest::~IDBRequest() | 90 IDBRequest::~IDBRequest() |
92 { | 91 { |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
177 } | 176 } |
178 | 177 |
179 void IDBRequest::setPendingCursor(PassRefPtr<IDBCursor> cursor) | 178 void IDBRequest::setPendingCursor(PassRefPtr<IDBCursor> cursor) |
180 { | 179 { |
181 ASSERT(m_readyState == DONE); | 180 ASSERT(m_readyState == DONE); |
182 ASSERT(scriptExecutionContext()); | 181 ASSERT(scriptExecutionContext()); |
183 ASSERT(m_transaction); | 182 ASSERT(m_transaction); |
184 ASSERT(!m_pendingCursor); | 183 ASSERT(!m_pendingCursor); |
185 ASSERT(cursor == getResultCursor()); | 184 ASSERT(cursor == getResultCursor()); |
186 | 185 |
186 m_hasPendingActivity = true; | |
187 m_pendingCursor = cursor; | 187 m_pendingCursor = cursor; |
188 m_result.clear(); | 188 m_result.clear(); |
189 m_readyState = PENDING; | 189 m_readyState = PENDING; |
190 m_error.clear(); | 190 m_error.clear(); |
191 m_transaction->registerRequest(this); | 191 m_transaction->registerRequest(this); |
192 } | 192 } |
193 | 193 |
194 PassRefPtr<IDBCursor> IDBRequest::getResultCursor() | 194 IDBCursor* IDBRequest::getResultCursor() |
195 { | 195 { |
196 if (!m_result) | 196 if (!m_result) |
197 return 0; | 197 return 0; |
198 if (m_result->type() == IDBAny::IDBCursorType) | 198 if (m_result->type() == IDBAny::IDBCursorType) |
199 return m_result->idbCursor(); | 199 return m_result->idbCursor(); |
200 if (m_result->type() == IDBAny::IDBCursorWithValueType) | 200 if (m_result->type() == IDBAny::IDBCursorWithValueType) |
201 return m_result->idbCursorWithValue(); | 201 return m_result->idbCursorWithValue(); |
202 return 0; | 202 return 0; |
203 } | 203 } |
204 | 204 |
205 void IDBRequest::setResultCursor(PassRefPtr<IDBCursor> cursor, PassRefPtr<IDBKey > key, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SharedBuffer> value) | 205 void IDBRequest::setResultCursor(PassRefPtr<IDBCursor> cursor, PassRefPtr<IDBKey > key, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SharedBuffer> value) |
206 { | 206 { |
207 ASSERT(m_readyState == PENDING); | 207 ASSERT(m_readyState == PENDING); |
208 m_cursorKey = key; | 208 m_cursorKey = key; |
209 m_cursorPrimaryKey = primaryKey; | 209 m_cursorPrimaryKey = primaryKey; |
210 m_cursorValue = value; | 210 m_cursorValue = value; |
211 | 211 |
212 if (m_cursorType == IndexedDB::CursorKeyOnly) { | 212 if (m_cursorType == IndexedDB::CursorKeyOnly) { |
213 m_result = IDBAny::create(cursor); | 213 m_result = IDBAny::create(cursor); |
214 return; | 214 return; |
215 } | 215 } |
216 | 216 |
217 m_result = IDBAny::create(IDBCursorWithValue::fromCursor(cursor)); | 217 m_result = IDBAny::create(IDBCursorWithValue::fromCursor(cursor)); |
218 } | 218 } |
219 | 219 |
220 void IDBRequest::finishCursor() | 220 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
| |
221 { | 221 { |
222 m_cursorFinished = true; | 222 // If this request and its cursor have the only references |
223 if (m_readyState != PENDING) | 223 // to each other, then explicitly break the cycle. |
224 m_hasPendingActivity = false; | 224 IDBCursor* cursor = getResultCursor(); |
225 if (!cursor || cursor->request() != this) | |
226 return; | |
227 | |
228 if (!hasOneRef() || !cursor->hasOneRef()) | |
229 return; | |
230 | |
231 m_result.clear(); | |
225 } | 232 } |
226 | 233 |
227 bool IDBRequest::shouldEnqueueEvent() const | 234 bool IDBRequest::shouldEnqueueEvent() const |
228 { | 235 { |
229 if (m_contextStopped || !scriptExecutionContext()) | 236 if (m_contextStopped || !scriptExecutionContext()) |
230 return false; | 237 return false; |
231 ASSERT(m_readyState == PENDING || m_readyState == DONE); | 238 ASSERT(m_readyState == PENDING || m_readyState == DONE); |
232 if (m_requestAborted) | 239 if (m_requestAborted) |
233 return false; | 240 return false; |
234 ASSERT(m_readyState == PENDING); | 241 ASSERT(m_readyState == PENDING); |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
489 } | 496 } |
490 | 497 |
491 // If this was the last request in the transaction's list, it may commit here. | 498 // If this was the last request in the transaction's list, it may commit here. |
492 if (setTransactionActive) | 499 if (setTransactionActive) |
493 m_transaction->setActive(false); | 500 m_transaction->setActive(false); |
494 } | 501 } |
495 | 502 |
496 if (cursorToNotify) | 503 if (cursorToNotify) |
497 cursorToNotify->postSuccessHandlerCallback(); | 504 cursorToNotify->postSuccessHandlerCallback(); |
498 | 505 |
499 if (m_readyState == DONE && (!cursorToNotify || m_cursorFinished) && event-> type() != eventNames().upgradeneededEvent) | 506 if (m_readyState == DONE && event->type() != eventNames().upgradeneededEvent ) |
500 m_hasPendingActivity = false; | 507 m_hasPendingActivity = false; |
501 | 508 |
502 return dontPreventDefault; | 509 return dontPreventDefault; |
503 } | 510 } |
504 | 511 |
505 void IDBRequest::uncaughtExceptionInEventHandler() | 512 void IDBRequest::uncaughtExceptionInEventHandler() |
506 { | 513 { |
507 if (m_transaction && !m_requestAborted) { | 514 if (m_transaction && !m_requestAborted) { |
508 m_transaction->setError(DOMError::create(AbortError, "Uncaught exception in event handler.")); | 515 m_transaction->setError(DOMError::create(AbortError, "Uncaught exception in event handler.")); |
509 m_transaction->abort(IGNORE_EXCEPTION); | 516 m_transaction->abort(IGNORE_EXCEPTION); |
(...skipping 30 matching lines...) Expand all Loading... | |
540 { | 547 { |
541 return &m_eventTargetData; | 548 return &m_eventTargetData; |
542 } | 549 } |
543 | 550 |
544 EventTargetData* IDBRequest::ensureEventTargetData() | 551 EventTargetData* IDBRequest::ensureEventTargetData() |
545 { | 552 { |
546 return &m_eventTargetData; | 553 return &m_eventTargetData; |
547 } | 554 } |
548 | 555 |
549 } // namespace WebCore | 556 } // namespace WebCore |
OLD | NEW |