void IDBDatabaseBackend::didOpenInternalAsync(const IDBDatabaseMetadata& metadata, bool success)
{
    if (!success) {
        processPendingOpenCalls(false);
        return;
    }

    m_metadata = metadata;

    processPendingCalls();
}
Example #2
0
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);
}