void StorageAreaSync::performSync() { ASSERT(!isMainThread()); bool clearItems; HashMap<String, String> items; { LockHolder locker(m_syncLock); ASSERT(m_syncScheduled); clearItems = m_clearItemsWhileSyncing; m_itemsPendingSync.swap(items); m_clearItemsWhileSyncing = false; m_syncScheduled = false; m_syncInProgress = true; } sync(clearItems, items); { LockHolder locker(m_syncLock); m_syncInProgress = false; } // The following is balanced by the call to disableSuddenTermination in the // syncTimerFired function. enableSuddenTermination(); }
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(); }
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(); } }