void IDBDatabaseBackend::deleteDatabase(PassRefPtr<IDBCallbacks> prpCallbacks) { RefPtr<IDBCallbacks> callbacks = prpCallbacks; if (isDeleteDatabaseBlocked()) { for (DatabaseCallbacksSet::const_iterator it = m_databaseCallbacksSet.begin(); it != m_databaseCallbacksSet.end(); ++it) { // Front end ensures the event is not fired at connections that have closePending set. (*it)->onVersionChange(m_metadata.version, 0, IndexedDB::NullVersion); } // FIXME: Only fire onBlocked if there are open connections after the // VersionChangeEvents are received, not just set up to fire. // https://bugs.webkit.org/show_bug.cgi?id=71130 callbacks->onBlocked(m_metadata.version); m_pendingDeleteCalls.append(IDBPendingDeleteCall::create(callbacks.release())); return; } deleteDatabaseAsync(callbacks.release()); }
void IDBDatabaseBackend::processPendingCalls() { // processPendingCalls() will be called again after openInternalAsync() completes. if (!m_didOpenInternal) return; if (m_pendingSecondHalfOpen) { ASSERT(m_pendingSecondHalfOpen->version() == m_metadata.version); ASSERT(m_metadata.id != InvalidId); m_pendingSecondHalfOpen->callbacks()->onSuccess(this, this->metadata()); m_pendingSecondHalfOpen = nullptr; // Fall through when complete, as pending deletes may be (partially) unblocked. } // Note that this check is only an optimization to reduce queue-churn and // not necessary for correctness; deleteDatabase and openConnection will // requeue their calls if this condition is true. if (m_runningVersionChangeTransaction) return; if (!m_pendingDeleteCalls.isEmpty() && isDeleteDatabaseBlocked()) return; while (!m_pendingDeleteCalls.isEmpty()) { std::unique_ptr<IDBPendingDeleteCall> pendingDeleteCall = m_pendingDeleteCalls.takeFirst(); m_deleteCallbacksWaitingCompletion.add(pendingDeleteCall->callbacks()); deleteDatabaseAsync(pendingDeleteCall->callbacks()); } // deleteDatabaseAsync should never re-queue calls. ASSERT(m_pendingDeleteCalls.isEmpty()); // If there are any database deletions waiting for completion, we're done for now. // Further callbacks will be handled in a future call to processPendingCalls(). if (!m_deleteCallbacksWaitingCompletion.isEmpty()) return; if (m_runningVersionChangeTransaction) return; processPendingOpenCalls(true); }