Exemplo n.º 1
0
void StorageAreaSync::scheduleItemForSync(const String& key, const String& value)
{
    ASSERT(isMainThread());
    ASSERT(!m_finalSyncScheduled);

    m_changedItems.set(key, value);
    if (!m_syncTimer.isActive()) {
        m_syncTimer.startOneShot(StorageSyncInterval);

        // The following is balanced by the call to enableSuddenTermination in the
        // syncTimerFired function.
        disableSuddenTermination();
    }
}
Exemplo n.º 2
0
void StorageAreaSync::scheduleClear()
{
    ASSERT(isMainThread());
    ASSERT(!m_finalSyncScheduled);

    m_changedItems.clear();
    m_itemsCleared = true;
    if (!m_syncTimer.isActive()) {
        m_syncTimer.startOneShot(StorageSyncInterval);

        // The following is balanced by the call to enableSuddenTermination in the
        // syncTimerFired function.
        disableSuddenTermination();
    }
}
Exemplo n.º 3
0
void StorageAreaSync::scheduleCloseDatabase()
{
    ASSERT(isMainThread());
    ASSERT(!m_finalSyncScheduled);

    if (!m_database.isOpen())
        return;

    m_syncCloseDatabase = true;
    
    if (!m_syncTimer.isActive()) {
        m_syncTimer.startOneShot(StorageSyncInterval);
        
        // The following is balanced by the call to enableSuddenTermination in the
        // syncTimerFired function.
        disableSuddenTermination();
    }
}
void StorageAreaSync::scheduleFinalSync()
{
    ASSERT(isMainThread());
    // FIXME: We do this to avoid races, but it'd be better to make things safe without blocking.
    blockUntilImportComplete();
    
    if (m_syncTimer.isActive())
        m_syncTimer.stop();
    else {
        // The following is balanced by the call to enableSuddenTermination in the
        // syncTimerFired function.
        disableSuddenTermination();
    }
    // FIXME: This is synchronous.  We should do it on the background process, but
    // we should do it safely.
    syncTimerFired(&m_syncTimer);
    m_finalSyncScheduled = true;
}
Exemplo n.º 5
0
void StorageAreaSync::scheduleFinalSync()
{
    ASSERT(isMainThread());
    // FIXME: We do this to avoid races, but it'd be better to make things safe without blocking.
    blockUntilImportComplete();
    m_storageArea = 0;  // This is done in blockUntilImportComplete() but this is here as a form of documentation that we must be absolutely sure the ref count cycle is broken.

    if (m_syncTimer.isActive())
        m_syncTimer.stop();
    else {
        // The following is balanced by the call to enableSuddenTermination in the
        // syncTimerFired function.
        disableSuddenTermination();
    }
    // FIXME: This is synchronous.  We should do it on the background process, but
    // we should do it safely.
    m_finalSyncScheduled = true;
    syncTimerFired(&m_syncTimer);
    m_syncManager->scheduleDeleteEmptyDatabase(this);
}
void StorageAreaSync::syncTimerFired(Timer<StorageAreaSync>*)
{
    ASSERT(isMainThread());

    HashMap<String, String>::iterator it = m_changedItems.begin();
    HashMap<String, String>::iterator end = m_changedItems.end();
    
    {
        MutexLocker locker(m_syncLock);

        if (m_itemsCleared) {
            m_itemsPendingSync.clear();
            m_clearItemsWhileSyncing = true;
            m_itemsCleared = false;
        }

        for (; it != end; ++it)
            m_itemsPendingSync.set(it->first.copy(), it->second.copy());

        if (!m_syncScheduled) {
            m_syncScheduled = true;

            // The following is balanced by the call to enableSuddenTermination in the
            // performSync function.
            disableSuddenTermination();

            m_syncManager->scheduleSync(this);
        }
    }

    // The following is balanced by the calls to disableSuddenTermination in the
    // scheduleItemForSync, scheduleClear, and scheduleFinalSync functions.
    enableSuddenTermination();

    m_changedItems.clear();
}
Exemplo n.º 7
0
void StorageAreaSync::syncTimerFired()
{
    ASSERT(isMainThread());

    bool partialSync = false;
    {
        LockHolder locker(m_syncLock);

        // Do not schedule another sync if we're still trying to complete the
        // previous one. But, if we're shutting down, schedule it anyway.
        if (m_syncInProgress && !m_finalSyncScheduled) {
            ASSERT(!m_syncTimer.isActive());
            m_syncTimer.startOneShot(StorageSyncInterval);
            return;
        }

        if (m_itemsCleared) {
            m_itemsPendingSync.clear();
            m_clearItemsWhileSyncing = true;
            m_itemsCleared = false;
        }

        HashMap<String, String>::iterator changed_it = m_changedItems.begin();
        HashMap<String, String>::iterator changed_end = m_changedItems.end();
        for (int count = 0; changed_it != changed_end; ++count, ++changed_it) {
            if (count >= MaxiumItemsToSync && !m_finalSyncScheduled) {
                partialSync = true;
                break;
            }
            m_itemsPendingSync.set(changed_it->key.isolatedCopy(), changed_it->value.isolatedCopy());
        }

        if (partialSync) {
            // We can't do the fast path of simply clearing all items, so we'll need to manually
            // remove them one by one. Done under lock since m_itemsPendingSync is modified by
            // the background thread.
            HashMap<String, String>::iterator pending_it = m_itemsPendingSync.begin();
            HashMap<String, String>::iterator pending_end = m_itemsPendingSync.end();
            for (; pending_it != pending_end; ++pending_it)
                m_changedItems.remove(pending_it->key);
        }

        if (!m_syncScheduled) {
            m_syncScheduled = true;

            // The following is balanced by the call to enableSuddenTermination in the
            // performSync function.
            disableSuddenTermination();

            RefPtr<StorageAreaSync> protector(this);
            m_syncManager->dispatch([protector] {
                protector->performSync();
            });
        }
    }

    if (partialSync) {
        // If we didn't finish syncing, then we need to finish the job later.
        ASSERT(!m_syncTimer.isActive());
        m_syncTimer.startOneShot(StorageSyncInterval);
    } else {
        // The following is balanced by the calls to disableSuddenTermination in the
        // scheduleItemForSync, scheduleClear, and scheduleFinalSync functions.
        enableSuddenTermination();

        m_changedItems.clear();
    }
}