void IDBDatabaseBackend::didOpenInternalAsync(const IDBDatabaseMetadata& metadata, bool success) { if (!success) { processPendingOpenCalls(false); return; } m_metadata = metadata; processPendingCalls(); }
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); }