summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authordavemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-24 21:05:36 +0000
committerdavemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-24 21:05:36 +0000
commit506cb1db9a466aad6b8d3fdce9cb94eb54516e47 (patch)
tree8959bc3c7ab135de91fa746bf416603cc6c98bdd /chrome
parent7b3c0312746e6f21478a01c3d56db4714b48618f (diff)
downloadchromium_src-506cb1db9a466aad6b8d3fdce9cb94eb54516e47.zip
chromium_src-506cb1db9a466aad6b8d3fdce9cb94eb54516e47.tar.gz
chromium_src-506cb1db9a466aad6b8d3fdce9cb94eb54516e47.tar.bz2
Reverting 27117.
Review URL: http://codereview.chromium.org/235010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27124 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/sync/engine/syncapi.cc13
-rw-r--r--chrome/browser/sync/engine/syncer_thread.cc317
-rw-r--r--chrome/browser/sync/engine/syncer_thread.h190
-rw-r--r--chrome/browser/sync/engine/syncer_thread_pthreads.cc578
-rw-r--r--chrome/browser/sync/engine/syncer_thread_pthreads.h284
-rw-r--r--chrome/browser/sync/engine/syncer_thread_timed_stop.cc119
-rw-r--r--chrome/browser/sync/engine/syncer_thread_timed_stop.h53
-rw-r--r--chrome/browser/sync/engine/syncer_thread_unittest.cc244
-rw-r--r--chrome/chrome.gyp5
-rw-r--r--chrome/common/chrome_switches.cc10
-rw-r--r--chrome/common/chrome_switches.h2
-rw-r--r--chrome/test/sync/engine/mock_server_connection.cc22
-rw-r--r--chrome/test/sync/engine/mock_server_connection.h9
-rw-r--r--chrome/test/sync/engine/test_directory_setter_upper.cc20
-rw-r--r--chrome/test/sync/engine/test_directory_setter_upper.h22
15 files changed, 257 insertions, 1631 deletions
diff --git a/chrome/browser/sync/engine/syncapi.cc b/chrome/browser/sync/engine/syncapi.cc
index b9a8695..f1ca43d 100644
--- a/chrome/browser/sync/engine/syncapi.cc
+++ b/chrome/browser/sync/engine/syncapi.cc
@@ -53,7 +53,6 @@ using browser_sync::Syncer;
using browser_sync::SyncerEvent;
using browser_sync::SyncerStatus;
using browser_sync::SyncerThread;
-using browser_sync::SyncerThreadFactory;
using browser_sync::UserSettings;
using browser_sync::TalkMediator;
using browser_sync::TalkMediatorImpl;
@@ -874,7 +873,7 @@ class SyncManager::SyncInternal {
scoped_ptr<SyncAPIServerConnectionManager> connection_manager_;
// The thread that runs the Syncer. Needs to be explicitly Start()ed.
- scoped_refptr<SyncerThread> syncer_thread_;
+ scoped_ptr<SyncerThread> syncer_thread_;
// Notification (xmpp) handler.
scoped_ptr<TalkMediator> talk_mediator_;
@@ -1064,11 +1063,11 @@ bool SyncManager::SyncInternal::Init(
// on the Syncer side, and |model_safe_worker| on the API client side.
ModelSafeWorkerBridge* worker = new ModelSafeWorkerBridge(model_safe_worker);
- syncer_thread_ = SyncerThreadFactory::Create(&command_channel_,
- dir_manager(),
- connection_manager(),
- &allstatus_,
- worker);
+ syncer_thread_.reset(new SyncerThread(&command_channel_,
+ dir_manager(),
+ connection_manager(),
+ &allstatus_,
+ worker));
syncer_thread()->WatchTalkMediator(talk_mediator());
allstatus()->WatchSyncerThread(syncer_thread());
diff --git a/chrome/browser/sync/engine/syncer_thread.cc b/chrome/browser/sync/engine/syncer_thread.cc
index 0ef436b..a53ab93 100644
--- a/chrome/browser/sync/engine/syncer_thread.cc
+++ b/chrome/browser/sync/engine/syncer_thread.cc
@@ -1,6 +1,7 @@
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+
#include "chrome/browser/sync/engine/syncer_thread.h"
#include "build/build_config.h"
@@ -15,23 +16,20 @@
#include <map>
#include <queue>
-#include "base/command_line.h"
#include "chrome/browser/sync/engine/auth_watcher.h"
#include "chrome/browser/sync/engine/model_safe_worker.h"
#include "chrome/browser/sync/engine/net/server_connection_manager.h"
#include "chrome/browser/sync/engine/syncer.h"
-#include "chrome/browser/sync/engine/syncer_thread_pthreads.h"
-#include "chrome/browser/sync/engine/syncer_thread_timed_stop.h"
#include "chrome/browser/sync/notifier/listener/talk_mediator.h"
#include "chrome/browser/sync/notifier/listener/talk_mediator_impl.h"
#include "chrome/browser/sync/syncable/directory_manager.h"
-#include "chrome/common/chrome_switches.h"
using std::priority_queue;
using std::min;
-using base::Time;
-using base::TimeDelta;
-using base::TimeTicks;
+
+static inline bool operator < (const timespec& a, const timespec& b) {
+ return a.tv_sec == b.tv_sec ? a.tv_nsec < b.tv_nsec : a.tv_sec < b.tv_sec;
+}
namespace {
@@ -110,56 +108,17 @@ int UserIdleTime() {
namespace browser_sync {
-SyncerThread* SyncerThreadFactory::Create(
- ClientCommandChannel* command_channel,
- syncable::DirectoryManager* mgr,
- ServerConnectionManager* connection_manager, AllStatus* all_status,
- ModelSafeWorker* model_safe_worker) {
- const CommandLine* cmd = CommandLine::ForCurrentProcess();
- if (cmd->HasSwitch(switches::kSyncerThreadTimedStop)) {
- return new SyncerThreadTimedStop(command_channel, mgr, connection_manager,
- all_status, model_safe_worker);
- } else if (cmd->HasSwitch(switches::kSyncerThreadPthreads)) {
- return new SyncerThreadPthreads(command_channel, mgr, connection_manager,
- all_status, model_safe_worker);
- } else {
- // The default SyncerThread implementation, which does not time-out when
- // Stop is called.
- return new SyncerThread(command_channel, mgr, connection_manager,
- all_status, model_safe_worker);
- }
-}
-
bool SyncerThread::NudgeSyncer(int milliseconds_from_now, NudgeSource source) {
- AutoLock lock(lock_);
- if (vault_.syncer_ == NULL) {
+ MutexLock lock(&mutex_);
+ if (syncer_ == NULL) {
return false;
}
NudgeSyncImpl(milliseconds_from_now, source);
return true;
}
-SyncerThread::SyncerThread()
- : thread_main_started_(false, false),
- thread_("SyncEngine_SyncerThread"),
- vault_field_changed_(&lock_),
- p2p_authenticated_(false),
- p2p_subscribed_(false),
- client_command_hookup_(NULL),
- conn_mgr_hookup_(NULL),
- allstatus_(NULL),
- dirman_(NULL),
- scm_(NULL),
- syncer_short_poll_interval_seconds_(kDefaultShortPollIntervalSeconds),
- syncer_long_poll_interval_seconds_(kDefaultLongPollIntervalSeconds),
- syncer_polling_interval_(kDefaultShortPollIntervalSeconds),
- syncer_max_interval_(kDefaultMaxPollIntervalMs),
- talk_mediator_hookup_(NULL),
- command_channel_(NULL),
- directory_manager_hookup_(NULL),
- syncer_events_(NULL),
- model_safe_worker_(NULL),
- disable_idle_detection_(false) {
+void* RunSyncerThread(void* syncer_thread) {
+ return (reinterpret_cast<SyncerThread*>(syncer_thread))->ThreadMain();
}
SyncerThread::SyncerThread(
@@ -168,14 +127,15 @@ SyncerThread::SyncerThread(
ServerConnectionManager* connection_manager,
AllStatus* all_status,
ModelSafeWorker* model_safe_worker)
- : thread_main_started_(false, false),
- thread_("SyncEngine_SyncerThread"),
- vault_field_changed_(&lock_),
+ : stop_syncer_thread_(false),
+ thread_running_(false),
+ connected_(false),
p2p_authenticated_(false),
p2p_subscribed_(false),
client_command_hookup_(NULL),
conn_mgr_hookup_(NULL),
allstatus_(all_status),
+ syncer_(NULL),
dirman_(mgr),
scm_(connection_manager),
syncer_short_poll_interval_seconds_(kDefaultShortPollIntervalSeconds),
@@ -212,76 +172,55 @@ SyncerThread::~SyncerThread() {
syncer_event_channel_.reset();
directory_manager_hookup_.reset();
syncer_events_.reset();
- delete vault_.syncer_;
+ delete syncer_;
talk_mediator_hookup_.reset();
- CHECK(!thread_.IsRunning());
+ CHECK(!thread_running_);
}
// Creates and starts a syncer thread.
// Returns true if it creates a thread or if there's currently a thread running
// and false otherwise.
bool SyncerThread::Start() {
- {
- AutoLock lock(lock_);
- if (thread_.IsRunning()) {
- return true;
- }
-
- if (!thread_.Start()) {
- return false;
- }
+ MutexLock lock(&mutex_);
+ if (thread_running_) {
+ return true;
}
-
- thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this,
- &SyncerThread::ThreadMain));
-
- // Wait for notification that our task makes it safely onto the message
- // loop before returning, so the caller can't call Stop before we're
- // actually up and running. This is for consistency with the old pthread
- // impl because pthread_create would do this in one step.
- thread_main_started_.Wait();
- LOG(INFO) << "SyncerThread started.";
- return true;
+ thread_running_ =
+ (0 == pthread_create(&thread_, NULL, RunSyncerThread, this));
+ if (thread_running_) {
+ pthread_detach(thread_);
+ }
+ return thread_running_;
}
// Stop processing. A max wait of at least 2*server RTT time is recommended.
// Returns true if we stopped, false otherwise.
bool SyncerThread::Stop(int max_wait) {
- {
- AutoLock lock(lock_);
- // If the thread has been started, then we either already have or are about
- // to enter ThreadMainLoop so we have to proceed with shutdown and wait for
- // it to finish. If the thread has not been started --and we now own the
- // lock-- then we can early out because the caller has not called Start().
- if (!thread_.IsRunning())
- return true;
-
- LOG(INFO) << "SyncerThread::Stop - setting ThreadMain exit condition to "
- << "true (vault_.stop_syncer_thread_)";
- // Exit the ThreadMainLoop once the syncer finishes (we tell it to exit
- // below).
- vault_.stop_syncer_thread_ = true;
- if (NULL != vault_.syncer_) {
- // Try to early exit the syncer itself, which could be looping inside
- // SyncShare.
- vault_.syncer_->RequestEarlyExit();
- }
-
- // stop_syncer_thread_ is now true and the Syncer has been told to exit.
- // We want to wake up all waiters so they can re-examine state. We signal,
- // causing all waiters to try to re-acquire the lock, and then we release
- // the lock, and join on our internal thread which should soon run off the
- // end of ThreadMain.
- vault_field_changed_.Broadcast();
+ MutexLock lock(&mutex_);
+ if (!thread_running_)
+ return true;
+ stop_syncer_thread_ = true;
+ if (NULL != syncer_) {
+ // Try to early exit the syncer.
+ syncer_->RequestEarlyExit();
}
-
- // This will join, and finish when ThreadMain terminates.
- thread_.Stop();
+ pthread_cond_broadcast(&changed_.condvar_);
+ timespec deadline = { time(NULL) + (max_wait / 1000), 0 };
+ do {
+ const int wait_result = max_wait < 0 ?
+ pthread_cond_wait(&changed_.condvar_, &mutex_.mutex_) :
+ pthread_cond_timedwait(&changed_.condvar_, &mutex_.mutex_,
+ &deadline);
+ if (ETIMEDOUT == wait_result) {
+ LOG(ERROR) << "SyncerThread::Stop timed out. Problems likely.";
+ return false;
+ }
+ } while (thread_running_);
return true;
}
void SyncerThread::WatchClientCommands(ClientCommandChannel* channel) {
- AutoLock lock(lock_);
+ PThreadScopedLock<PThreadMutex> lock(&mutex_);
client_command_hookup_.reset(NewEventListenerHookup(channel, this,
&SyncerThread::HandleClientCommand));
}
@@ -302,89 +241,67 @@ void SyncerThread::HandleClientCommand(ClientCommandChannel::EventType event) {
}
void SyncerThread::ThreadMainLoop() {
- // This is called with lock_ acquired.
- lock_.AssertAcquired();
- LOG(INFO) << "In thread main loop.";
-
// Use the short poll value by default.
- TimeDelta poll_seconds =
- TimeDelta::FromSeconds(syncer_short_poll_interval_seconds_);
+ int poll_seconds = syncer_short_poll_interval_seconds_;
int user_idle_milliseconds = 0;
- TimeTicks last_sync_time;
+ timespec last_sync_time = { 0 };
bool initial_sync_for_thread = true;
bool continue_sync_cycle = false;
- while (!vault_.stop_syncer_thread_) {
- // The Wait()s in these conditionals using |vault_| are not TimedWait()s (as
- // below) because we cannot poll until these conditions are met, so we wait
- // indefinitely.
- if (!vault_.connected_) {
+ while (!stop_syncer_thread_) {
+ if (!connected_) {
LOG(INFO) << "Syncer thread waiting for connection.";
- while (!vault_.connected_ && !vault_.stop_syncer_thread_)
- vault_field_changed_.Wait();
- LOG_IF(INFO, vault_.connected_) << "Syncer thread found connection.";
+ while (!connected_ && !stop_syncer_thread_)
+ pthread_cond_wait(&changed_.condvar_, &mutex_.mutex_);
+ LOG_IF(INFO, connected_) << "Syncer thread found connection.";
continue;
}
- if (vault_.syncer_ == NULL) {
+ if (syncer_ == NULL) {
LOG(INFO) << "Syncer thread waiting for database initialization.";
- while (vault_.syncer_ == NULL && !vault_.stop_syncer_thread_)
- vault_field_changed_.Wait();
- LOG_IF(INFO, !(vault_.syncer_ == NULL))
- << "Syncer was found after DB started.";
+ while (syncer_ == NULL && !stop_syncer_thread_)
+ pthread_cond_wait(&changed_.condvar_, &mutex_.mutex_);
+ LOG_IF(INFO, !(syncer_ == NULL)) << "Syncer was found after DB started.";
continue;
}
- const TimeTicks next_poll = last_sync_time + poll_seconds;
- const TimeTicks end_wait =
- !vault_.nudge_queue_.empty() &&
- vault_.nudge_queue_.top().first < next_poll ?
- vault_.nudge_queue_.top().first : next_poll;
- LOG(INFO) << "end_wait is " << end_wait.ToInternalValue();
- LOG(INFO) << "next_poll is " << next_poll.ToInternalValue();
-
- // We block until the CV is signaled (e.g a control field changed, loss of
- // network connection, nudge, spurious, etc), or the poll interval elapses.
- TimeDelta sleep_time = end_wait - TimeTicks::Now();
- if (sleep_time > TimeDelta::FromSeconds(0)) {
- vault_field_changed_.TimedWait(sleep_time);
-
- if (TimeTicks::Now() < end_wait) {
- // Didn't timeout. Could be a spurious signal, or a signal corresponding
- // to an actual change in one of our control fields. By continuing here
- // we perform the typical "always recheck conditions when signaled",
- // (typically handled by a while(condition_not_met) cv.wait() construct)
- // because we jump to the top of the loop. The main difference is we
- // recalculate the wait interval, but last_sync_time won't have changed.
- // So if we were signaled by a nudge (for ex.) we'll grab the new nudge
- // off the queue and wait for that delta. If it was a spurious signal,
- // we'll keep waiting for the same moment in time as we just were.
- continue;
- }
+ timespec const next_poll = { last_sync_time.tv_sec + poll_seconds,
+ last_sync_time.tv_nsec };
+ const timespec wake_time =
+ !nudge_queue_.empty() && nudge_queue_.top().first < next_poll ?
+ nudge_queue_.top().first : next_poll;
+ LOG(INFO) << "wake time is " << wake_time.tv_sec;
+ LOG(INFO) << "next poll is " << next_poll.tv_sec;
+
+ const int error = pthread_cond_timedwait(&changed_.condvar_, &mutex_.mutex_,
+ &wake_time);
+ if (ETIMEDOUT != error) {
+ continue; // Check all the conditions again.
}
+ const timespec now = GetPThreadAbsoluteTime(0);
+
// Handle a nudge, caused by either a notification or a local bookmark
// event. This will also update the source of the following SyncMain call.
- UpdateNudgeSource(&continue_sync_cycle, &initial_sync_for_thread);
+ UpdateNudgeSource(now, &continue_sync_cycle, &initial_sync_for_thread);
- LOG(INFO) << "Calling Sync Main at time " << Time::Now().ToInternalValue();
- SyncMain(vault_.syncer_);
- last_sync_time = TimeTicks::Now();
+ LOG(INFO) << "Calling Sync Main at time " << now.tv_sec;
+ SyncMain(syncer_);
+ last_sync_time = now;
LOG(INFO) << "Updating the next polling time after SyncMain";
- poll_seconds = TimeDelta::FromSeconds(CalculatePollingWaitTime(
- allstatus_->status(), static_cast<int>(poll_seconds.InSeconds()),
- &user_idle_milliseconds, &continue_sync_cycle));
+ poll_seconds = CalculatePollingWaitTime(allstatus_->status(),
+ poll_seconds,
+ &user_idle_milliseconds,
+ &continue_sync_cycle);
}
-
}
// We check how long the user's been idle and sync less often if the machine is
// not in use. The aim is to reduce server load.
-// TODO(timsteele): Should use Time(Delta).
int SyncerThread::CalculatePollingWaitTime(
const AllStatus::Status& status,
- int last_poll_wait, // Time in seconds.
+ int last_poll_wait, // in s
int* user_idle_milliseconds,
bool* continue_sync_cycle) {
bool is_continuing_sync_cyle = *continue_sync_cycle;
@@ -435,25 +352,30 @@ int SyncerThread::CalculatePollingWaitTime(
return actual_next_wait;
}
-void SyncerThread::ThreadMain() {
- AutoLock lock(lock_);
- // Signal Start() to let it know we've made it safely onto the message loop,
- // and unblock it's caller.
- thread_main_started_.Signal();
+void* SyncerThread::ThreadMain() {
+ NameCurrentThreadForDebugging("SyncEngine_SyncerThread");
+ mutex_.Lock();
ThreadMainLoop();
- LOG(INFO) << "Syncer thread ThreadMain is done.";
+ thread_running_ = false;
+ pthread_cond_broadcast(&changed_.condvar_);
+ mutex_.Unlock();
+ LOG(INFO) << "Syncer thread exiting.";
+ return 0;
}
void SyncerThread::SyncMain(Syncer* syncer) {
CHECK(syncer);
- AutoUnlock unlock(lock_);
+ mutex_.Unlock();
while (syncer->SyncShare()) {
LOG(INFO) << "Looping in sync share";
}
LOG(INFO) << "Done looping in sync share";
+
+ mutex_.Lock();
}
-void SyncerThread::UpdateNudgeSource(bool* continue_sync_cycle,
+void SyncerThread::UpdateNudgeSource(const timespec& now,
+ bool* continue_sync_cycle,
bool* initial_sync) {
bool nudged = false;
NudgeSource nudge_source = kUnknown;
@@ -463,14 +385,13 @@ void SyncerThread::UpdateNudgeSource(bool* continue_sync_cycle,
}
// Update the nudge source if a new nudge has come through during the
// previous sync cycle.
- while (!vault_.nudge_queue_.empty() &&
- TimeTicks::Now() >= vault_.nudge_queue_.top().first) {
+ while (!nudge_queue_.empty() && !(now < nudge_queue_.top().first)) {
if (!nudged) {
- nudge_source = vault_.nudge_queue_.top().second;
+ nudge_source = nudge_queue_.top().second;
*continue_sync_cycle = false; // Reset the continuation token on nudge.
nudged = true;
}
- vault_.nudge_queue_.pop();
+ nudge_queue_.pop();
}
SetUpdatesSource(nudged, nudge_source, initial_sync);
}
@@ -501,11 +422,11 @@ void SyncerThread::SetUpdatesSource(bool nudged, NudgeSource nudge_source,
break;
}
}
- vault_.syncer_->set_updates_source(updates_source);
+ syncer_->set_updates_source(updates_source);
}
void SyncerThread::HandleSyncerEvent(const SyncerEvent& event) {
- AutoLock lock(lock_);
+ MutexLock lock(&mutex_);
channel()->NotifyListeners(event);
if (SyncerEvent::REQUEST_SYNC_NUDGE != event.what_happened) {
return;
@@ -517,33 +438,33 @@ void SyncerThread::HandleDirectoryManagerEvent(
const syncable::DirectoryManagerEvent& event) {
LOG(INFO) << "Handling a directory manager event";
if (syncable::DirectoryManagerEvent::OPENED == event.what_happened) {
- AutoLock lock(lock_);
+ MutexLock lock(&mutex_);
LOG(INFO) << "Syncer starting up for: " << event.dirname;
// The underlying database structure is ready, and we should create
// the syncer.
- CHECK(vault_.syncer_ == NULL);
- vault_.syncer_ =
+ CHECK(syncer_ == NULL);
+ syncer_ =
new Syncer(dirman_, event.dirname, scm_, model_safe_worker_.get());
- vault_.syncer_->set_command_channel(command_channel_);
+ syncer_->set_command_channel(command_channel_);
syncer_events_.reset(NewEventListenerHookup(
- vault_.syncer_->channel(), this, &SyncerThread::HandleSyncerEvent));
- vault_field_changed_.Broadcast();
+ syncer_->channel(), this, &SyncerThread::HandleSyncerEvent));
+ pthread_cond_broadcast(&changed_.condvar_);
}
}
static inline void CheckConnected(bool* connected,
HttpResponse::ServerConnectionCode code,
- ConditionVariable* condvar) {
+ pthread_cond_t* condvar) {
if (*connected) {
if (HttpResponse::CONNECTION_UNAVAILABLE == code) {
*connected = false;
- condvar->Broadcast();
+ pthread_cond_broadcast(condvar);
}
} else {
if (HttpResponse::SERVER_CONNECTION_OK == code) {
*connected = true;
- condvar->Broadcast();
+ pthread_cond_broadcast(condvar);
}
}
}
@@ -551,16 +472,16 @@ static inline void CheckConnected(bool* connected,
void SyncerThread::WatchConnectionManager(ServerConnectionManager* conn_mgr) {
conn_mgr_hookup_.reset(NewEventListenerHookup(conn_mgr->channel(), this,
&SyncerThread::HandleServerConnectionEvent));
- CheckConnected(&vault_.connected_, conn_mgr->server_status(),
- &vault_field_changed_);
+ CheckConnected(&connected_, conn_mgr->server_status(),
+ &changed_.condvar_);
}
void SyncerThread::HandleServerConnectionEvent(
const ServerConnectionEvent& event) {
if (ServerConnectionEvent::STATUS_CHANGED == event.what_happened) {
- AutoLock lock(lock_);
- CheckConnected(&vault_.connected_, event.connection_code,
- &vault_field_changed_);
+ MutexLock lock(&mutex_);
+ CheckConnected(&connected_, event.connection_code,
+ &changed_.condvar_);
}
}
@@ -592,11 +513,10 @@ int SyncerThread::CalculateSyncWaitTime(int last_interval, int user_idle_ms) {
// Called with mutex_ already locked.
void SyncerThread::NudgeSyncImpl(int milliseconds_from_now,
NudgeSource source) {
- const TimeTicks nudge_time = TimeTicks::Now() +
- TimeDelta::FromMilliseconds(milliseconds_from_now);
+ const timespec nudge_time = GetPThreadAbsoluteTime(milliseconds_from_now);
NudgeObject nudge_object(nudge_time, source);
- vault_.nudge_queue_.push(nudge_object);
- vault_field_changed_.Broadcast();
+ nudge_queue_.push(nudge_object);
+ pthread_cond_broadcast(&changed_.condvar_);
}
void SyncerThread::WatchTalkMediator(TalkMediator* mediator) {
@@ -608,7 +528,7 @@ void SyncerThread::WatchTalkMediator(TalkMediator* mediator) {
}
void SyncerThread::HandleTalkMediatorEvent(const TalkMediatorEvent& event) {
- AutoLock lock(lock_);
+ MutexLock lock(&mutex_);
switch (event.what_happened) {
case TalkMediatorEvent::LOGIN_SUCCEEDED:
LOG(INFO) << "P2P: Login succeeded.";
@@ -621,7 +541,7 @@ void SyncerThread::HandleTalkMediatorEvent(const TalkMediatorEvent& event) {
case TalkMediatorEvent::SUBSCRIPTIONS_ON:
LOG(INFO) << "P2P: Subscriptions successfully enabled.";
p2p_subscribed_ = true;
- if (NULL != vault_.syncer_) {
+ if (NULL != syncer_) {
LOG(INFO) << "Subscriptions on. Nudging syncer for initial push.";
NudgeSyncImpl(0, kLocal);
}
@@ -632,7 +552,7 @@ void SyncerThread::HandleTalkMediatorEvent(const TalkMediatorEvent& event) {
break;
case TalkMediatorEvent::NOTIFICATION_RECEIVED:
LOG(INFO) << "P2P: Updates on server, pushing syncer";
- if (NULL != vault_.syncer_) {
+ if (NULL != syncer_) {
NudgeSyncImpl(0, kNotification);
}
break;
@@ -640,9 +560,8 @@ void SyncerThread::HandleTalkMediatorEvent(const TalkMediatorEvent& event) {
break;
}
- if (NULL != vault_.syncer_) {
- vault_.syncer_->set_notifications_enabled(
- p2p_authenticated_ && p2p_subscribed_);
+ if (NULL != syncer_) {
+ syncer_->set_notifications_enabled(p2p_authenticated_ && p2p_subscribed_);
}
}
diff --git a/chrome/browser/sync/engine/syncer_thread.h b/chrome/browser/sync/engine/syncer_thread.h
index 4d1ae95..ca22969e 100644
--- a/chrome/browser/sync/engine/syncer_thread.h
+++ b/chrome/browser/sync/engine/syncer_thread.h
@@ -3,8 +3,7 @@
// found in the LICENSE file.
//
// A class to run the syncer on a thread.
-// This is the default implementation of SyncerThread whose Stop implementation
-// does not support a timeout, but is greatly simplified.
+
#ifndef CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_H_
#define CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_H_
@@ -14,15 +13,11 @@
#include <vector>
#include "base/basictypes.h"
-#include "base/condition_variable.h"
-#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
-#include "base/thread.h"
-#include "base/time.h"
-#include "base/waitable_event.h"
#include "chrome/browser/sync/engine/all_status.h"
#include "chrome/browser/sync/engine/client_command_channel.h"
#include "chrome/browser/sync/util/event_sys-inl.h"
+#include "chrome/browser/sync/util/pthread_helpers.h"
#include "testing/gtest/include/gtest/gtest_prod.h" // For FRIEND_TEST
class EventListenerHookup;
@@ -44,42 +39,20 @@ struct SyncerEvent;
struct SyncerShutdownEvent;
struct TalkMediatorEvent;
-class SyncerThreadFactory {
- public:
- // Creates a SyncerThread based on the default (or user-overridden)
- // implementation. The thread does not start running until you call Start(),
- // which will cause it to check-and-wait for certain conditions to be met
- // (such as valid connection with Server established, syncable::Directory has
- // been opened) before performing an intial sync with a server. It uses
- // |connection_manager| to detect valid connections, and |mgr| to detect the
- // opening of a Directory, which will cause it to create a Syncer object for
- // said Directory, and assign |model_safe_worker| to it. |connection_manager|
- // and |mgr| should outlive the SyncerThread. You must stop the thread by
- // calling Stop before destroying the object. Stopping will first tear down
- // the Syncer object, allowing it to finish work in progress, before joining
- // the Stop-calling thread with the internal thread.
- static SyncerThread* Create(ClientCommandChannel* command_channel,
- syncable::DirectoryManager* mgr,
- ServerConnectionManager* connection_manager, AllStatus* all_status,
- ModelSafeWorker* model_safe_worker);
- private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(SyncerThreadFactory);
-};
-
-class SyncerThread : public base::RefCountedThreadSafe<SyncerThread> {
+class SyncerThread {
FRIEND_TEST(SyncerThreadTest, CalculateSyncWaitTime);
FRIEND_TEST(SyncerThreadTest, CalculatePollingWaitTime);
- FRIEND_TEST(SyncerThreadWithSyncerTest, Polling);
- FRIEND_TEST(SyncerThreadWithSyncerTest, Nudge);
- friend class SyncerThreadWithSyncerTest;
- friend class SyncerThreadFactory;
-public:
+
+ public:
+ friend class SyncerThreadTest;
+
enum NudgeSource {
kUnknown = 0,
kNotification,
kLocal,
kContinuation
};
+
// Server can overwrite these values via client commands.
// Standard short poll. This is used when XMPP is off.
static const int kDefaultShortPollIntervalSeconds = 60;
@@ -89,106 +62,54 @@ public:
// longest possible poll interval.
static const int kDefaultMaxPollIntervalMs = 30 * 60 * 1000;
- virtual ~SyncerThread();
-
- virtual void WatchConnectionManager(ServerConnectionManager* conn_mgr);
+ SyncerThread(ClientCommandChannel* command_channel,
+ syncable::DirectoryManager* mgr,
+ ServerConnectionManager* connection_manager, AllStatus* all_status,
+ ModelSafeWorker* model_safe_worker);
+ ~SyncerThread();
- // Starts a syncer thread.
+ void WatchConnectionManager(ServerConnectionManager* conn_mgr);
+ // Creates and starts a syncer thread.
// Returns true if it creates a thread or if there's currently a thread
// running and false otherwise.
- virtual bool Start();
+ bool Start();
- // Stop processing. |max_wait| doesn't do anything in this version.
- virtual bool Stop(int max_wait);
+ // Stop processing. A max wait of at least 2*server RTT time is recommended.
+ // returns true if we stopped, false otherwise.
+ bool Stop(int max_wait);
- // Nudges the syncer to sync with a delay specified. This API is for access
+ // Nudges the syncer to sync with a delay specified. This API is for access
// from the SyncerThread's controller and will cause a mutex lock.
- virtual bool NudgeSyncer(int milliseconds_from_now, NudgeSource source);
+ bool NudgeSyncer(int milliseconds_from_now, NudgeSource source);
// Registers this thread to watch talk mediator events.
- virtual void WatchTalkMediator(TalkMediator* talk_mediator);
-
- virtual void WatchClientCommands(ClientCommandChannel* channel);
-
- virtual SyncerEventChannel* channel();
+ void WatchTalkMediator(TalkMediator* talk_mediator);
- protected:
- SyncerThread(); // Necessary for temporary pthreads-based PIMPL impl.
- SyncerThread(ClientCommandChannel* command_channel,
- syncable::DirectoryManager* mgr,
- ServerConnectionManager* connection_manager, AllStatus* all_status,
- ModelSafeWorker* model_safe_worker);
- virtual void ThreadMain();
- void ThreadMainLoop();
+ void WatchClientCommands(ClientCommandChannel* channel);
- virtual void SetConnected(bool connected) {
- DCHECK(!thread_.IsRunning());
- vault_.connected_ = connected;
- }
-
- virtual void SetSyncerPollingInterval(base::TimeDelta interval) {
- // TODO(timsteele): Use TimeDelta internally.
- syncer_polling_interval_ = static_cast<int>(interval.InSeconds());
- }
- virtual void SetSyncerShortPollInterval(base::TimeDelta interval) {
- // TODO(timsteele): Use TimeDelta internally.
- syncer_short_poll_interval_seconds_ =
- static_cast<int>(interval.InSeconds());
- }
-
- // Needed to emulate the behavior of pthread_create, which synchronously
- // started the thread and set the value of thread_running_ to true.
- // We can't quite match that because we asynchronously post the task,
- // which opens a window for Stop to get called before the task actually
- // makes it. To prevent this, we block Start() until we're sure it's ok.
- base::WaitableEvent thread_main_started_;
+ SyncerEventChannel* channel();
- // Handle of the running thread.
- base::Thread thread_;
+ private:
+ // A few members to gate the rate at which we nudge the syncer.
+ enum {
+ kNudgeRateLimitCount = 6,
+ kNudgeRateLimitTime = 180,
+ };
- typedef std::pair<base::TimeTicks, NudgeSource> NudgeObject;
+ // A queue of all scheduled nudges. One insertion for every call to
+ // NudgeQueue().
+ typedef std::pair<timespec, NudgeSource> NudgeObject;
- struct IsTimeTicksGreater {
+ struct IsTimeSpecGreater {
inline bool operator() (const NudgeObject& lhs, const NudgeObject& rhs) {
- return lhs.first > rhs.first;
+ return lhs.first.tv_sec == rhs.first.tv_sec ?
+ lhs.first.tv_nsec > rhs.first.tv_nsec :
+ lhs.first.tv_sec > rhs.first.tv_sec;
}
};
typedef std::priority_queue<NudgeObject, std::vector<NudgeObject>,
- IsTimeTicksGreater> NudgeQueue;
-
- // Fields that are modified / accessed by multiple threads go in this struct
- // for clarity and explicitness.
- struct ProtectedFields {
- // False when we want to stop the thread.
- bool stop_syncer_thread_;
-
- Syncer* syncer_;
-
- // State of the server connection.
- bool connected_;
-
- // A queue of all scheduled nudges. One insertion for every call to
- // NudgeQueue().
- NudgeQueue nudge_queue_;
-
- ProtectedFields()
- : stop_syncer_thread_(false), syncer_(NULL), connected_(false) {}
- } vault_;
-
- // Gets signaled whenever a thread outside of the syncer thread changes a
- // protected field in the vault_.
- ConditionVariable vault_field_changed_;
-
- // Used to lock everything in |vault_|.
- Lock lock_;
-
- private:
- // A few members to gate the rate at which we nudge the syncer.
- enum {
- kNudgeRateLimitCount = 6,
- kNudgeRateLimitTime = 180,
- };
+ IsTimeSpecGreater> NudgeQueue;
// Threshold multipler for how long before user should be considered idle.
static const int kPollBackoffThresholdMultiplier = 10;
@@ -204,6 +125,9 @@ public:
void HandleTalkMediatorEvent(const TalkMediatorEvent& event);
+ void* ThreadMain();
+ void ThreadMainLoop();
+
void SyncMain(Syncer* syncer);
// Calculates the next sync wait time in seconds. last_poll_wait is the time
@@ -213,24 +137,42 @@ public:
// continue_sync_cycle parameter is used to determine whether or not we are
// calculating a polling wait time that is a continuation of an sync cycle
// which terminated while the syncer still had work to do.
- virtual int CalculatePollingWaitTime(
+ int CalculatePollingWaitTime(
const AllStatus::Status& status,
int last_poll_wait, // in s
int* user_idle_milliseconds,
bool* continue_sync_cycle);
// Helper to above function, considers effect of user idle time.
- virtual int CalculateSyncWaitTime(int last_wait, int user_idle_ms);
+ int CalculateSyncWaitTime(int last_wait, int user_idle_ms);
// Sets the source value of the controlled syncer's updates_source value.
// The initial sync boolean is updated if read as a sentinel. The following
// two methods work in concert to achieve this goal.
- void UpdateNudgeSource(bool* continue_sync_cycle,
+ void UpdateNudgeSource(const timespec& now, bool* continue_sync_cycle,
bool* initial_sync);
void SetUpdatesSource(bool nudged, NudgeSource nudge_source,
bool* initial_sync);
// For unit tests only.
- virtual void DisableIdleDetection() { disable_idle_detection_ = true; }
+ void DisableIdleDetection() { disable_idle_detection_ = true; }
+
+ // False when we want to stop the thread.
+ bool stop_syncer_thread_;
+
+ // We use one mutex for all members except the channel.
+ PThreadMutex mutex_;
+ typedef PThreadScopedLock<PThreadMutex> MutexLock;
+
+ // Handle of the running thread.
+ pthread_t thread_;
+ bool thread_running_;
+
+ // Gets signaled whenever a thread outside of the syncer thread changes a
+ // member variable.
+ PThreadCondVar changed_;
+
+ // State of the server connection.
+ bool connected_;
// State of the notification framework is tracked by these values.
bool p2p_authenticated_;
@@ -240,6 +182,8 @@ public:
scoped_ptr<EventListenerHookup> conn_mgr_hookup_;
const AllStatus* allstatus_;
+ Syncer* syncer_;
+
syncable::DirectoryManager* dirman_;
ServerConnectionManager* scm_;
@@ -264,6 +208,8 @@ public:
// this is called.
void NudgeSyncImpl(int milliseconds_from_now, NudgeSource source);
+ NudgeQueue nudge_queue_;
+
scoped_ptr<EventListenerHookup> talk_mediator_hookup_;
ClientCommandChannel* const command_channel_;
scoped_ptr<EventListenerHookup> directory_manager_hookup_;
@@ -282,4 +228,4 @@ public:
} // namespace browser_sync
-#endif // CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_H_ \ No newline at end of file
+#endif // CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_H_
diff --git a/chrome/browser/sync/engine/syncer_thread_pthreads.cc b/chrome/browser/sync/engine/syncer_thread_pthreads.cc
deleted file mode 100644
index 9fdfb21..0000000
--- a/chrome/browser/sync/engine/syncer_thread_pthreads.cc
+++ /dev/null
@@ -1,578 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#include "chrome/browser/sync/engine/syncer_thread_pthreads.h"
-
-#include "build/build_config.h"
-
-#ifdef OS_MACOSX
-#include <CoreFoundation/CFNumber.h>
-#include <IOKit/IOTypes.h>
-#include <IOKit/IOKitLib.h>
-#endif
-
-#include <algorithm>
-#include <map>
-#include <queue>
-
-#include "chrome/browser/sync/engine/auth_watcher.h"
-#include "chrome/browser/sync/engine/model_safe_worker.h"
-#include "chrome/browser/sync/engine/net/server_connection_manager.h"
-#include "chrome/browser/sync/engine/syncer.h"
-#include "chrome/browser/sync/notifier/listener/talk_mediator.h"
-#include "chrome/browser/sync/notifier/listener/talk_mediator_impl.h"
-#include "chrome/browser/sync/syncable/directory_manager.h"
-
-using std::priority_queue;
-using std::min;
-
-static inline bool operator < (const timespec& a, const timespec& b) {
- return a.tv_sec == b.tv_sec ? a.tv_nsec < b.tv_nsec : a.tv_sec < b.tv_sec;
-}
-
-namespace {
-
-// Returns the amount of time since the user last interacted with the computer,
-// in milliseconds
-int UserIdleTime() {
-#ifdef OS_WIN
- LASTINPUTINFO last_input_info;
- last_input_info.cbSize = sizeof(LASTINPUTINFO);
-
- // Get time in windows ticks since system start of last activity.
- BOOL b = ::GetLastInputInfo(&last_input_info);
- if (b == TRUE)
- return ::GetTickCount() - last_input_info.dwTime;
-#elif defined(OS_MACOSX)
- // It would be great to do something like:
- //
- // return 1000 *
- // CGEventSourceSecondsSinceLastEventType(
- // kCGEventSourceStateCombinedSessionState,
- // kCGAnyInputEventType);
- //
- // Unfortunately, CGEvent* lives in ApplicationServices, and we're a daemon
- // and can't link that high up the food chain. Thus this mucking in IOKit.
-
- io_service_t hid_service =
- IOServiceGetMatchingService(kIOMasterPortDefault,
- IOServiceMatching("IOHIDSystem"));
- if (!hid_service) {
- LOG(WARNING) << "Could not obtain IOHIDSystem";
- return 0;
- }
-
- CFTypeRef object = IORegistryEntryCreateCFProperty(hid_service,
- CFSTR("HIDIdleTime"),
- kCFAllocatorDefault,
- 0);
- if (!object) {
- LOG(WARNING) << "Could not get IOHIDSystem's HIDIdleTime property";
- IOObjectRelease(hid_service);
- return 0;
- }
-
- int64 idle_time; // in nanoseconds
- Boolean success;
- if (CFGetTypeID(object) == CFNumberGetTypeID()) {
- success = CFNumberGetValue((CFNumberRef)object,
- kCFNumberSInt64Type,
- &idle_time);
- } else {
- LOG(WARNING) << "IOHIDSystem's HIDIdleTime property isn't a number!";
- }
-
- CFRelease(object);
- IOObjectRelease(hid_service);
-
- if (!success) {
- LOG(WARNING) << "Could not get IOHIDSystem's HIDIdleTime property's value";
- return 0;
- } else {
- return idle_time / 1000000; // nano to milli
- }
-#else
- static bool was_logged = false;
- if (!was_logged) {
- was_logged = true;
- LOG(INFO) << "UserIdleTime unimplemented on this platform, "
- "synchronization will not throttle when user idle";
- }
-#endif
-
- return 0;
-}
-
-} // namespace
-
-namespace browser_sync {
-
-SyncerThreadPthreads::SyncerThreadPthreads(
- ClientCommandChannel* command_channel,
- syncable::DirectoryManager* mgr,
- ServerConnectionManager* connection_manager,
- AllStatus* all_status, ModelSafeWorker* model_safe_worker)
- : SyncerThread() {
- impl_.reset(new SyncerThreadPthreadImpl(command_channel, mgr,
- connection_manager, all_status, model_safe_worker));
-}
-
-bool SyncerThreadPthreadImpl::NudgeSyncer(int milliseconds_from_now,
- SyncerThread::NudgeSource source) {
- MutexLock lock(&mutex_);
- if (syncer_ == NULL) {
- return false;
- }
- NudgeSyncImpl(milliseconds_from_now, source);
- return true;
-}
-
-void* RunSyncerThread(void* syncer_thread) {
- return (reinterpret_cast<SyncerThreadPthreadImpl*>(
- syncer_thread))->ThreadMain();
-}
-
-SyncerThreadPthreadImpl::SyncerThreadPthreadImpl(
- ClientCommandChannel* command_channel,
- syncable::DirectoryManager* mgr,
- ServerConnectionManager* connection_manager,
- AllStatus* all_status,
- ModelSafeWorker* model_safe_worker)
- : dirman_(mgr), scm_(connection_manager),
- syncer_(NULL), syncer_events_(NULL), thread_running_(false),
- syncer_short_poll_interval_seconds_(
- SyncerThread::kDefaultShortPollIntervalSeconds),
- syncer_long_poll_interval_seconds_(
- SyncerThread::kDefaultLongPollIntervalSeconds),
- syncer_polling_interval_(SyncerThread::kDefaultShortPollIntervalSeconds),
- syncer_max_interval_(SyncerThread::kDefaultMaxPollIntervalMs),
- stop_syncer_thread_(false), connected_(false), conn_mgr_hookup_(NULL),
- p2p_authenticated_(false), p2p_subscribed_(false),
- allstatus_(all_status), talk_mediator_hookup_(NULL),
- command_channel_(command_channel), directory_manager_hookup_(NULL),
- model_safe_worker_(model_safe_worker),
- client_command_hookup_(NULL), disable_idle_detection_(false) {
-
- SyncerEvent shutdown = { SyncerEvent::SHUTDOWN_USE_WITH_CARE };
- syncer_event_channel_.reset(new SyncerEventChannel(shutdown));
-
- if (dirman_) {
- directory_manager_hookup_.reset(NewEventListenerHookup(
- dirman_->channel(), this,
- &SyncerThreadPthreadImpl::HandleDirectoryManagerEvent));
- }
-
- if (scm_) {
- WatchConnectionManager(scm_);
- }
-
- if (command_channel_) {
- WatchClientCommands(command_channel_);
- }
-}
-
-SyncerThreadPthreadImpl::~SyncerThreadPthreadImpl() {
- client_command_hookup_.reset();
- conn_mgr_hookup_.reset();
- syncer_event_channel_.reset();
- directory_manager_hookup_.reset();
- syncer_events_.reset();
- delete syncer_;
- talk_mediator_hookup_.reset();
- CHECK(!thread_running_);
-}
-
-// Creates and starts a syncer thread.
-// Returns true if it creates a thread or if there's currently a thread running
-// and false otherwise.
-bool SyncerThreadPthreadImpl::Start() {
- MutexLock lock(&mutex_);
- if (thread_running_) {
- return true;
- }
- thread_running_ =
- (0 == pthread_create(&thread_, NULL, RunSyncerThread, this));
- if (thread_running_) {
- pthread_detach(thread_);
- }
- return thread_running_;
-}
-
-// Stop processing. A max wait of at least 2*server RTT time is recommended.
-// Returns true if we stopped, false otherwise.
-bool SyncerThreadPthreadImpl::Stop(int max_wait) {
- MutexLock lock(&mutex_);
- if (!thread_running_)
- return true;
- stop_syncer_thread_ = true;
- if (NULL != syncer_) {
- // Try to early exit the syncer.
- syncer_->RequestEarlyExit();
- }
- pthread_cond_broadcast(&changed_.condvar_);
- timespec deadline = { time(NULL) + (max_wait / 1000), 0 };
- do {
- const int wait_result = max_wait < 0 ?
- pthread_cond_wait(&changed_.condvar_, &mutex_.mutex_) :
- pthread_cond_timedwait(&changed_.condvar_, &mutex_.mutex_,
- &deadline);
- if (ETIMEDOUT == wait_result) {
- LOG(ERROR) << "SyncerThread::Stop timed out. Problems likely.";
- return false;
- }
- } while (thread_running_);
- return true;
-}
-
-void SyncerThreadPthreadImpl::WatchClientCommands(
- ClientCommandChannel* channel) {
- PThreadScopedLock<PThreadMutex> lock(&mutex_);
- client_command_hookup_.reset(NewEventListenerHookup(channel, this,
- &SyncerThreadPthreadImpl::HandleClientCommand));
-}
-
-void SyncerThreadPthreadImpl::HandleClientCommand(
- ClientCommandChannel::EventType event) {
- if (!event) {
- return;
- }
-
- // Mutex not really necessary for these.
- if (event->has_set_sync_poll_interval()) {
- syncer_short_poll_interval_seconds_ = event->set_sync_poll_interval();
- }
-
- if (event->has_set_sync_long_poll_interval()) {
- syncer_long_poll_interval_seconds_ = event->set_sync_long_poll_interval();
- }
-}
-
-void SyncerThreadPthreadImpl::ThreadMainLoop() {
- // Use the short poll value by default.
- int poll_seconds = syncer_short_poll_interval_seconds_;
- int user_idle_milliseconds = 0;
- timespec last_sync_time = { 0 };
- bool initial_sync_for_thread = true;
- bool continue_sync_cycle = false;
-
- while (!stop_syncer_thread_) {
- if (!connected_) {
- LOG(INFO) << "Syncer thread waiting for connection.";
- while (!connected_ && !stop_syncer_thread_)
- pthread_cond_wait(&changed_.condvar_, &mutex_.mutex_);
- LOG_IF(INFO, connected_) << "Syncer thread found connection.";
- continue;
- }
-
- if (syncer_ == NULL) {
- LOG(INFO) << "Syncer thread waiting for database initialization.";
- while (syncer_ == NULL && !stop_syncer_thread_)
- pthread_cond_wait(&changed_.condvar_, &mutex_.mutex_);
- LOG_IF(INFO, !(syncer_ == NULL)) << "Syncer was found after DB started.";
- continue;
- }
-
- timespec const next_poll = { last_sync_time.tv_sec + poll_seconds,
- last_sync_time.tv_nsec };
- const timespec wake_time =
- !nudge_queue_.empty() && nudge_queue_.top().first < next_poll ?
- nudge_queue_.top().first : next_poll;
- LOG(INFO) << "wake time is " << wake_time.tv_sec;
- LOG(INFO) << "next poll is " << next_poll.tv_sec;
-
- const int error = pthread_cond_timedwait(&changed_.condvar_, &mutex_.mutex_,
- &wake_time);
- if (ETIMEDOUT != error) {
- continue; // Check all the conditions again.
- }
-
- const timespec now = GetPThreadAbsoluteTime(0);
-
- // Handle a nudge, caused by either a notification or a local bookmark
- // event. This will also update the source of the following SyncMain call.
- UpdateNudgeSource(now, &continue_sync_cycle, &initial_sync_for_thread);
-
- LOG(INFO) << "Calling Sync Main at time " << now.tv_sec;
- SyncMain(syncer_);
- last_sync_time = now;
-
- LOG(INFO) << "Updating the next polling time after SyncMain";
- poll_seconds = CalculatePollingWaitTime(allstatus_->status(),
- poll_seconds,
- &user_idle_milliseconds,
- &continue_sync_cycle);
- }
-}
-
-// We check how long the user's been idle and sync less often if the machine is
-// not in use. The aim is to reduce server load.
-int SyncerThreadPthreadImpl::CalculatePollingWaitTime(
- const AllStatus::Status& status,
- int last_poll_wait, // in s
- int* user_idle_milliseconds,
- bool* continue_sync_cycle) {
- bool is_continuing_sync_cyle = *continue_sync_cycle;
- *continue_sync_cycle = false;
-
- // Determine if the syncer has unfinished work to do from allstatus_.
- const bool syncer_has_work_to_do =
- status.updates_available > status.updates_received
- || status.unsynced_count > 0;
- LOG(INFO) << "syncer_has_work_to_do is " << syncer_has_work_to_do;
-
- // First calculate the expected wait time, figuring in any backoff because of
- // user idle time. next_wait is in seconds
- syncer_polling_interval_ = (!status.notifications_enabled) ?
- syncer_short_poll_interval_seconds_ :
- syncer_long_poll_interval_seconds_;
- int default_next_wait = syncer_polling_interval_;
- int actual_next_wait = default_next_wait;
-
- if (syncer_has_work_to_do) {
- // Provide exponential backoff due to consecutive errors, else attempt to
- // complete the work as soon as possible.
- if (!is_continuing_sync_cyle) {
- actual_next_wait = AllStatus::GetRecommendedDelaySeconds(0);
- } else {
- actual_next_wait = AllStatus::GetRecommendedDelaySeconds(last_poll_wait);
- }
- *continue_sync_cycle = true;
- } else if (!status.notifications_enabled) {
- // Ensure that we start exponential backoff from our base polling
- // interval when we are not continuing a sync cycle.
- last_poll_wait = std::max(last_poll_wait, syncer_polling_interval_);
-
- // Did the user start interacting with the computer again?
- // If so, revise our idle time (and probably next_sync_time) downwards
- int new_idle_time = disable_idle_detection_ ? 0 : UserIdleTime();
- if (new_idle_time < *user_idle_milliseconds) {
- *user_idle_milliseconds = new_idle_time;
- }
- actual_next_wait = CalculateSyncWaitTime(last_poll_wait * 1000,
- *user_idle_milliseconds) / 1000;
- DCHECK_GE(actual_next_wait, default_next_wait);
- }
-
- LOG(INFO) << "Sync wait: idle " << default_next_wait
- << " non-idle or backoff " << actual_next_wait << ".";
-
- return actual_next_wait;
-}
-
-void* SyncerThreadPthreadImpl::ThreadMain() {
- NameCurrentThreadForDebugging("SyncEngine_SyncerThread");
- mutex_.Lock();
- ThreadMainLoop();
- thread_running_ = false;
- pthread_cond_broadcast(&changed_.condvar_);
- mutex_.Unlock();
- LOG(INFO) << "Syncer thread exiting.";
- return 0;
-}
-
-void SyncerThreadPthreadImpl::SyncMain(Syncer* syncer) {
- CHECK(syncer);
- mutex_.Unlock();
- while (syncer->SyncShare()) {
- LOG(INFO) << "Looping in sync share";
- }
- LOG(INFO) << "Done looping in sync share";
-
- mutex_.Lock();
-}
-
-void SyncerThreadPthreadImpl::UpdateNudgeSource(const timespec& now,
- bool* continue_sync_cycle,
- bool* initial_sync) {
- bool nudged = false;
- SyncerThread::NudgeSource nudge_source = SyncerThread::kUnknown;
- // Has the previous sync cycle completed?
- if (continue_sync_cycle) {
- nudge_source = SyncerThread::kContinuation;
- }
- // Update the nudge source if a new nudge has come through during the
- // previous sync cycle.
- while (!nudge_queue_.empty() && !(now < nudge_queue_.top().first)) {
- if (!nudged) {
- nudge_source = nudge_queue_.top().second;
- *continue_sync_cycle = false; // Reset the continuation token on nudge.
- nudged = true;
- }
- nudge_queue_.pop();
- }
- SetUpdatesSource(nudged, nudge_source, initial_sync);
-}
-
-void SyncerThreadPthreadImpl::SetUpdatesSource(bool nudged,
- SyncerThread::NudgeSource nudge_source, bool* initial_sync) {
- sync_pb::GetUpdatesCallerInfo::GET_UPDATES_SOURCE updates_source =
- sync_pb::GetUpdatesCallerInfo::UNKNOWN;
- if (*initial_sync) {
- updates_source = sync_pb::GetUpdatesCallerInfo::FIRST_UPDATE;
- *initial_sync = false;
- } else if (!nudged) {
- updates_source = sync_pb::GetUpdatesCallerInfo::PERIODIC;
- } else {
- switch (nudge_source) {
- case SyncerThread::kNotification:
- updates_source = sync_pb::GetUpdatesCallerInfo::NOTIFICATION;
- break;
- case SyncerThread::kLocal:
- updates_source = sync_pb::GetUpdatesCallerInfo::LOCAL;
- break;
- case SyncerThread::kContinuation:
- updates_source = sync_pb::GetUpdatesCallerInfo::SYNC_CYCLE_CONTINUATION;
- break;
- case SyncerThread::kUnknown:
- default:
- updates_source = sync_pb::GetUpdatesCallerInfo::UNKNOWN;
- break;
- }
- }
- syncer_->set_updates_source(updates_source);
-}
-
-void SyncerThreadPthreadImpl::HandleSyncerEvent(const SyncerEvent& event) {
- MutexLock lock(&mutex_);
- channel()->NotifyListeners(event);
- if (SyncerEvent::REQUEST_SYNC_NUDGE != event.what_happened) {
- return;
- }
- NudgeSyncImpl(event.nudge_delay_milliseconds, SyncerThread::kUnknown);
-}
-
-void SyncerThreadPthreadImpl::HandleDirectoryManagerEvent(
- const syncable::DirectoryManagerEvent& event) {
- LOG(INFO) << "Handling a directory manager event";
- if (syncable::DirectoryManagerEvent::OPENED == event.what_happened) {
- MutexLock lock(&mutex_);
- LOG(INFO) << "Syncer starting up for: " << event.dirname;
- // The underlying database structure is ready, and we should create
- // the syncer.
- CHECK(syncer_ == NULL);
- syncer_ =
- new Syncer(dirman_, event.dirname, scm_, model_safe_worker_.get());
-
- syncer_->set_command_channel(command_channel_);
- syncer_events_.reset(NewEventListenerHookup(
- syncer_->channel(), this, &SyncerThreadPthreadImpl::HandleSyncerEvent));
- pthread_cond_broadcast(&changed_.condvar_);
- }
-}
-
-static inline void CheckConnected(bool* connected,
- HttpResponse::ServerConnectionCode code,
- pthread_cond_t* condvar) {
- if (*connected) {
- if (HttpResponse::CONNECTION_UNAVAILABLE == code) {
- *connected = false;
- pthread_cond_broadcast(condvar);
- }
- } else {
- if (HttpResponse::SERVER_CONNECTION_OK == code) {
- *connected = true;
- pthread_cond_broadcast(condvar);
- }
- }
-}
-
-void SyncerThreadPthreadImpl::WatchConnectionManager(
- ServerConnectionManager* conn_mgr) {
- conn_mgr_hookup_.reset(NewEventListenerHookup(conn_mgr->channel(), this,
- &SyncerThreadPthreadImpl::HandleServerConnectionEvent));
- CheckConnected(&connected_, conn_mgr->server_status(),
- &changed_.condvar_);
-}
-
-void SyncerThreadPthreadImpl::HandleServerConnectionEvent(
- const ServerConnectionEvent& event) {
- if (ServerConnectionEvent::STATUS_CHANGED == event.what_happened) {
- MutexLock lock(&mutex_);
- CheckConnected(&connected_, event.connection_code,
- &changed_.condvar_);
- }
-}
-
-SyncerEventChannel* SyncerThreadPthreadImpl::channel() {
- return syncer_event_channel_.get();
-}
-
-// Inputs and return value in milliseconds.
-int SyncerThreadPthreadImpl::CalculateSyncWaitTime(int last_interval,
- int user_idle_ms) {
- // syncer_polling_interval_ is in seconds
- int syncer_polling_interval_ms = syncer_polling_interval_ * 1000;
-
- // This is our default and lower bound.
- int next_wait = syncer_polling_interval_ms;
-
- // Get idle time, bounded by max wait.
- int idle = min(user_idle_ms, syncer_max_interval_);
-
- // If the user has been idle for a while, we'll start decreasing the poll
- // rate.
- if (idle >= kPollBackoffThresholdMultiplier * syncer_polling_interval_ms) {
- next_wait = std::min(AllStatus::GetRecommendedDelaySeconds(
- last_interval / 1000), syncer_max_interval_ / 1000) * 1000;
- }
-
- return next_wait;
-}
-
-// Called with mutex_ already locked.
-void SyncerThreadPthreadImpl::NudgeSyncImpl(int milliseconds_from_now,
- SyncerThread::NudgeSource source) {
- const timespec nudge_time = GetPThreadAbsoluteTime(milliseconds_from_now);
- NudgeObject nudge_object(nudge_time, source);
- nudge_queue_.push(nudge_object);
- pthread_cond_broadcast(&changed_.condvar_);
-}
-
-void SyncerThreadPthreadImpl::WatchTalkMediator(TalkMediator* mediator) {
- talk_mediator_hookup_.reset(
- NewEventListenerHookup(
- mediator->channel(),
- this,
- &SyncerThreadPthreadImpl::HandleTalkMediatorEvent));
-}
-
-void SyncerThreadPthreadImpl::HandleTalkMediatorEvent(
- const TalkMediatorEvent& event) {
- MutexLock lock(&mutex_);
- switch (event.what_happened) {
- case TalkMediatorEvent::LOGIN_SUCCEEDED:
- LOG(INFO) << "P2P: Login succeeded.";
- p2p_authenticated_ = true;
- break;
- case TalkMediatorEvent::LOGOUT_SUCCEEDED:
- LOG(INFO) << "P2P: Login succeeded.";
- p2p_authenticated_ = false;
- break;
- case TalkMediatorEvent::SUBSCRIPTIONS_ON:
- LOG(INFO) << "P2P: Subscriptions successfully enabled.";
- p2p_subscribed_ = true;
- if (NULL != syncer_) {
- LOG(INFO) << "Subscriptions on. Nudging syncer for initial push.";
- NudgeSyncImpl(0, SyncerThread::kLocal);
- }
- break;
- case TalkMediatorEvent::SUBSCRIPTIONS_OFF:
- LOG(INFO) << "P2P: Subscriptions are not enabled.";
- p2p_subscribed_ = false;
- break;
- case TalkMediatorEvent::NOTIFICATION_RECEIVED:
- LOG(INFO) << "P2P: Updates on server, pushing syncer";
- if (NULL != syncer_) {
- NudgeSyncImpl(0, SyncerThread::kNotification);
- }
- break;
- default:
- break;
- }
-
- if (NULL != syncer_) {
- syncer_->set_notifications_enabled(p2p_authenticated_ && p2p_subscribed_);
- }
-}
-
-} // namespace browser_sync \ No newline at end of file
diff --git a/chrome/browser/sync/engine/syncer_thread_pthreads.h b/chrome/browser/sync/engine/syncer_thread_pthreads.h
deleted file mode 100644
index bebd8ed..0000000
--- a/chrome/browser/sync/engine/syncer_thread_pthreads.h
+++ /dev/null
@@ -1,284 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// *THIS EXISTS FOR EXPERIMENTATION AND TESTING WHILE WE REPLACE PTHREADS
-// WITH CHROME THREADS IN SYNC CODE*
-
-// A class to run the syncer on a thread. Uses PIMPL to wrap the old, original
-// pthreads implementation of SyncerThread.
-#ifndef CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_PTHREADS_H_
-#define CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_PTHREADS_H_
-
-#include <list>
-#include <map>
-#include <queue>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/scoped_ptr.h"
-#include "chrome/browser/sync/engine/all_status.h"
-#include "chrome/browser/sync/engine/client_command_channel.h"
-#include "chrome/browser/sync/util/event_sys-inl.h"
-#include "chrome/browser/sync/util/pthread_helpers.h"
-#include "chrome/browser/sync/engine/syncer_thread.h"
-#include "testing/gtest/include/gtest/gtest_prod.h" // For FRIEND_TEST
-
-class EventListenerHookup;
-
-namespace syncable {
-class DirectoryManager;
-struct DirectoryManagerEvent;
-}
-
-namespace browser_sync {
-
-class ModelSafeWorker;
-class ServerConnectionManager;
-class Syncer;
-class TalkMediator;
-class URLFactory;
-struct ServerConnectionEvent;
-struct SyncerEvent;
-struct SyncerShutdownEvent;
-struct TalkMediatorEvent;
-
-// The legacy implementation of SyncerThread using pthreads, kept around for
-// historical experimentation until a new version is finalized.
-class SyncerThreadPthreadImpl {
- public:
- virtual ~SyncerThreadPthreadImpl();
-
- virtual void WatchConnectionManager(ServerConnectionManager* conn_mgr);
- // Creates and starts a syncer thread.
- // Returns true if it creates a thread or if there's currently a thread
- // running and false otherwise.
- virtual bool Start();
-
- // Stop processing. A max wait of at least 2*server RTT time is recommended.
- // returns true if we stopped, false otherwise.
- virtual bool Stop(int max_wait);
-
- // Nudges the syncer to sync with a delay specified. This API is for access
- // from the SyncerThread's controller and will cause a mutex lock.
- virtual bool NudgeSyncer(int milliseconds_from_now,
- SyncerThread::NudgeSource source);
-
- // Registers this thread to watch talk mediator events.
- virtual void WatchTalkMediator(TalkMediator* talk_mediator);
-
- virtual void WatchClientCommands(ClientCommandChannel* channel);
-
- virtual SyncerEventChannel* channel();
-
- private:
- friend class SyncerThreadPthreads;
- SyncerThreadPthreadImpl(ClientCommandChannel* command_channel,
- syncable::DirectoryManager* mgr,
- ServerConnectionManager* connection_manager, AllStatus* all_status,
- ModelSafeWorker* model_safe_worker);
-
- // A few members to gate the rate at which we nudge the syncer.
- enum {
- kNudgeRateLimitCount = 6,
- kNudgeRateLimitTime = 180,
- };
-
- // A queue of all scheduled nudges. One insertion for every call to
- // NudgeQueue().
- typedef std::pair<timespec, SyncerThread::NudgeSource> NudgeObject;
-
- struct IsTimeSpecGreater {
- inline bool operator() (const NudgeObject& lhs, const NudgeObject& rhs) {
- return lhs.first.tv_sec == rhs.first.tv_sec ?
- lhs.first.tv_nsec > rhs.first.tv_nsec :
- lhs.first.tv_sec > rhs.first.tv_sec;
- }
- };
-
- typedef std::priority_queue<NudgeObject, std::vector<NudgeObject>,
- IsTimeSpecGreater> NudgeQueue;
-
- // Threshold multipler for how long before user should be considered idle.
- static const int kPollBackoffThresholdMultiplier = 10;
-
- friend void* RunSyncerThread(void* syncer_thread);
- void* Run();
- void HandleDirectoryManagerEvent(
- const syncable::DirectoryManagerEvent& event);
- void HandleSyncerEvent(const SyncerEvent& event);
- void HandleClientCommand(ClientCommandChannel::EventType event);
-
- void HandleServerConnectionEvent(const ServerConnectionEvent& event);
-
- void HandleTalkMediatorEvent(const TalkMediatorEvent& event);
-
- void* ThreadMain();
- void ThreadMainLoop();
-
- void SyncMain(Syncer* syncer);
-
- // Calculates the next sync wait time in seconds. last_poll_wait is the time
- // duration of the previous polling timeout which was used.
- // user_idle_milliseconds is updated by this method, and is a report of the
- // full amount of time since the last period of activity for the user. The
- // continue_sync_cycle parameter is used to determine whether or not we are
- // calculating a polling wait time that is a continuation of an sync cycle
- // which terminated while the syncer still had work to do.
- int CalculatePollingWaitTime(
- const AllStatus::Status& status,
- int last_poll_wait, // in s
- int* user_idle_milliseconds,
- bool* continue_sync_cycle);
- // Helper to above function, considers effect of user idle time.
- int CalculateSyncWaitTime(int last_wait, int user_idle_ms);
-
- // Sets the source value of the controlled syncer's updates_source value.
- // The initial sync boolean is updated if read as a sentinel. The following
- // two methods work in concert to achieve this goal.
- void UpdateNudgeSource(const timespec& now, bool* continue_sync_cycle,
- bool* initial_sync);
- void SetUpdatesSource(bool nudged, SyncerThread::NudgeSource nudge_source,
- bool* initial_sync);
-
- // For unit tests only.
- void DisableIdleDetection() { disable_idle_detection_ = true; }
-
- // False when we want to stop the thread.
- bool stop_syncer_thread_;
-
- // We use one mutex for all members except the channel.
- PThreadMutex mutex_;
- typedef PThreadScopedLock<PThreadMutex> MutexLock;
-
- // Handle of the running thread.
- pthread_t thread_;
- bool thread_running_;
-
- // Gets signaled whenever a thread outside of the syncer thread changes a
- // member variable.
- PThreadCondVar changed_;
-
- // State of the server connection.
- bool connected_;
-
- // State of the notification framework is tracked by these values.
- bool p2p_authenticated_;
- bool p2p_subscribed_;
-
- scoped_ptr<EventListenerHookup> client_command_hookup_;
- scoped_ptr<EventListenerHookup> conn_mgr_hookup_;
- const AllStatus* allstatus_;
-
- Syncer* syncer_;
-
- syncable::DirectoryManager* dirman_;
- ServerConnectionManager* scm_;
-
- // Modifiable versions of kDefaultLongPollIntervalSeconds which can be
- // updated by the server.
- int syncer_short_poll_interval_seconds_;
- int syncer_long_poll_interval_seconds_;
-
- // The time we wait between polls in seconds. This is used as lower bound on
- // our wait time. Updated once per loop from the command line flag.
- int syncer_polling_interval_;
-
- // The upper bound on the nominal wait between polls in seconds. Note that
- // this bounds the "nominal" poll interval, while the the actual interval
- // also takes previous failures into account.
- int syncer_max_interval_;
-
- scoped_ptr<SyncerEventChannel> syncer_event_channel_;
-
- // This causes syncer to start syncing ASAP. If the rate of requests is too
- // high the request will be silently dropped. mutex_ should be held when
- // this is called.
- void NudgeSyncImpl(int milliseconds_from_now,
- SyncerThread::NudgeSource source);
-
- NudgeQueue nudge_queue_;
-
- scoped_ptr<EventListenerHookup> talk_mediator_hookup_;
- ClientCommandChannel* const command_channel_;
- scoped_ptr<EventListenerHookup> directory_manager_hookup_;
- scoped_ptr<EventListenerHookup> syncer_events_;
-
- // Handles any tasks that will result in model changes (modifications of
- // syncable::Entries). Pass this to the syncer created and managed by |this|.
- // Only non-null in syncapi case.
- scoped_ptr<ModelSafeWorker> model_safe_worker_;
-
- // Useful for unit tests
- bool disable_idle_detection_;
-
- DISALLOW_COPY_AND_ASSIGN(SyncerThreadPthreadImpl);
-};
-
-// A new-version SyncerThread pimpl wrapper for the old legacy implementation.
-class SyncerThreadPthreads : public SyncerThread {
- FRIEND_TEST(SyncerThreadTest, CalculateSyncWaitTime);
- FRIEND_TEST(SyncerThreadTest, CalculatePollingWaitTime);
- FRIEND_TEST(SyncerThreadWithSyncerTest, Polling);
- FRIEND_TEST(SyncerThreadWithSyncerTest, Nudge);
- friend class SyncerThreadWithSyncerTest;
- friend class SyncerThreadFactory;
- public:
- virtual ~SyncerThreadPthreads() {}
-
- virtual void WatchConnectionManager(ServerConnectionManager* conn_mgr) {
- impl_->WatchConnectionManager(conn_mgr);
- }
- virtual bool Start() {
- return impl_->Start();
- }
- virtual bool Stop(int max_wait) {
- return impl_->Stop(max_wait);
- }
- virtual bool NudgeSyncer(int milliseconds_from_now, NudgeSource source) {
- return impl_->NudgeSyncer(milliseconds_from_now, source);
- }
- virtual void WatchTalkMediator(TalkMediator* talk_mediator) {
- impl_->WatchTalkMediator(talk_mediator);
- }
- virtual void WatchClientCommands(ClientCommandChannel* channel) {
- impl_->WatchClientCommands(channel);
- }
- virtual SyncerEventChannel* channel() {
- return impl_->channel();
- }
- protected:
- SyncerThreadPthreads(ClientCommandChannel* command_channel,
- syncable::DirectoryManager* mgr,
- ServerConnectionManager* connection_manager, AllStatus* all_status,
- ModelSafeWorker* model_safe_worker);
- virtual void SetConnected(bool connected) {
- impl_->connected_ = connected;
- }
- virtual void SetSyncerPollingInterval(int interval) {
- impl_->syncer_polling_interval_ = interval;
- }
- virtual void SetSyncerShortPollInterval(base::TimeDelta interval) {
- impl_->syncer_short_poll_interval_seconds_ = static_cast<int>(
- interval.InSeconds());
- }
- virtual void DisableIdleDetection() { impl_->disable_idle_detection_ = true; }
- virtual int CalculateSyncWaitTime(int last_wait, int user_idle_ms) {
- return impl_->CalculateSyncWaitTime(last_wait, user_idle_ms);
- }
- virtual int CalculatePollingWaitTime(
- const AllStatus::Status& status,
- int last_poll_wait, // in s
- int* user_idle_milliseconds,
- bool* continue_sync_cycle) {
- return impl_->CalculatePollingWaitTime(status, last_poll_wait,
- user_idle_milliseconds, continue_sync_cycle);
- }
- private:
- scoped_ptr<SyncerThreadPthreadImpl> impl_;
- DISALLOW_COPY_AND_ASSIGN(SyncerThreadPthreads);
-};
-
-} // namespace browser_sync
-
-#endif // CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_PTHREADS_H_ \ No newline at end of file
diff --git a/chrome/browser/sync/engine/syncer_thread_timed_stop.cc b/chrome/browser/sync/engine/syncer_thread_timed_stop.cc
deleted file mode 100644
index a396dd0..0000000
--- a/chrome/browser/sync/engine/syncer_thread_timed_stop.cc
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#include "chrome/browser/sync/engine/syncer_thread_timed_stop.h"
-
-#include "build/build_config.h"
-
-#ifdef OS_MACOSX
-#include <CoreFoundation/CFNumber.h>
-#include <IOKit/IOTypes.h>
-#include <IOKit/IOKitLib.h>
-#endif
-
-#include <algorithm>
-#include <map>
-#include <queue>
-
-#include "chrome/browser/sync/engine/auth_watcher.h"
-#include "chrome/browser/sync/engine/model_safe_worker.h"
-#include "chrome/browser/sync/engine/net/server_connection_manager.h"
-#include "chrome/browser/sync/engine/syncer.h"
-#include "chrome/browser/sync/notifier/listener/talk_mediator.h"
-#include "chrome/browser/sync/notifier/listener/talk_mediator_impl.h"
-#include "chrome/browser/sync/syncable/directory_manager.h"
-
-using std::priority_queue;
-using std::min;
-using base::Time;
-using base::TimeDelta;
-using base::TimeTicks;
-
-namespace browser_sync {
-
-SyncerThreadTimedStop::SyncerThreadTimedStop(
- ClientCommandChannel* command_channel,
- syncable::DirectoryManager* mgr,
- ServerConnectionManager* connection_manager,
- AllStatus* all_status,
- ModelSafeWorker* model_safe_worker)
- : SyncerThread(command_channel, mgr, connection_manager, all_status,
- model_safe_worker),
- in_thread_main_loop_(false) {
-}
-
-// Stop processing. A max wait of at least 2*server RTT time is recommended.
-// Returns true if we stopped, false otherwise.
-bool SyncerThreadTimedStop::Stop(int max_wait) {
- AutoLock lock(lock_);
- // If the thread has been started, then we either already have or are about to
- // enter ThreadMainLoop so we have to proceed with shutdown and wait for it to
- // finish. If the thread has not been started --and we now own the lock--
- // then we can early out because the caller has not called Start().
- if (!thread_.IsRunning())
- return true;
-
- LOG(INFO) << "SyncerThread::Stop - setting ThreadMain exit condition to "
- << "true (vault_.stop_syncer_thread_)";
- // Exit the ThreadMainLoop once the syncer finishes (we tell it to exit
- // below).
- vault_.stop_syncer_thread_ = true;
- if (NULL != vault_.syncer_) {
- // Try to early exit the syncer.
- vault_.syncer_->RequestEarlyExit();
- }
-
- // stop_syncer_thread_ is now true and the Syncer has been told to exit.
- // We want to wake up all waiters so they can re-examine state. We signal,
- // causing all waiters to try to re-acquire the lock, and then we atomically
- // release the lock and wait. Our wait can be spuriously signaled, so we
- // recalculate the remaining sleep time each time through and re-
- // check the condition before exiting the loop.
- vault_field_changed_.Broadcast();
- TimeTicks start = TimeTicks::Now();
- TimeTicks end = start + TimeDelta::FromMilliseconds(max_wait);
- bool timed_out = false;
- // Eventually the combination of RequestEarlyExit and setting
- // stop_syncer_thread_ to true above will cause in_thread_main_loop_ to become
- // false.
- while (in_thread_main_loop_) {
- TimeDelta sleep_time = end - TimeTicks::Now();
- if (sleep_time < TimeDelta::FromSeconds(0)) {
- timed_out = true;
- break;
- }
- LOG(INFO) << "Waiting in stop for " << sleep_time.InSeconds() << "s.";
- vault_field_changed_.TimedWait(sleep_time);
- }
-
- if (timed_out) {
- LOG(ERROR) << "SyncerThread::Stop timed out or error. Problems likely.";
- return false;
- }
-
- // Stop() should not block on anything at this point, given above madness.
- DLOG(INFO) << "Calling SyncerThread::thread_.Stop() at "
- << Time::Now().ToInternalValue();
- thread_.Stop();
- DLOG(INFO) << "SyncerThread::thread_.Stop() finished at "
- << Time::Now().ToInternalValue();
- return true;
-}
-
-void SyncerThreadTimedStop::ThreadMain() {
- AutoLock lock(lock_);
- // Signal Start() to let it know we've made it safely are now running on the
- // message loop, and unblock it's caller.
- thread_main_started_.Signal();
-
- // The only thing that could be waiting on this value is Stop, and we don't
- // release the lock until we're far enough along to Stop safely.
- in_thread_main_loop_ = true;
- vault_field_changed_.Broadcast();
- ThreadMainLoop();
- in_thread_main_loop_ = false;
- vault_field_changed_.Broadcast();
- LOG(INFO) << "Syncer thread ThreadMain is done.";
-}
-
-} // namespace browser_sync \ No newline at end of file
diff --git a/chrome/browser/sync/engine/syncer_thread_timed_stop.h b/chrome/browser/sync/engine/syncer_thread_timed_stop.h
deleted file mode 100644
index e1037a1..0000000
--- a/chrome/browser/sync/engine/syncer_thread_timed_stop.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// A class to run the syncer on a thread. This guy is the closest chrome-based
-// (as opposed to pthreads based) SyncerThread to the old pthread implementation
-// in semantics, as it supports a timeout on Stop() -- It is just an override of
-// two methods from SyncerThread: ThreadMain and Stop -- to provide this.
-#ifndef CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_TIMED_STOP_H_
-#define CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_TIMED_STOP_H_
-
-#include <list>
-#include <map>
-#include <queue>
-#include <vector>
-
-#include "chrome/browser/sync/engine/syncer_thread.h"
-
-namespace browser_sync {
-
-class SyncerThreadTimedStop : public SyncerThread {
- FRIEND_TEST(SyncerThreadTest, CalculateSyncWaitTime);
- FRIEND_TEST(SyncerThreadTest, CalculatePollingWaitTime);
- FRIEND_TEST(SyncerThreadWithSyncerTest, Polling);
- FRIEND_TEST(SyncerThreadWithSyncerTest, Nudge);
- friend class SyncerThreadWithSyncerTest;
- friend class SyncerThreadFactory;
- public:
- virtual ~SyncerThreadTimedStop() {}
-
- // Stop processing. This version comes with a supported max_wait.
- // A max wait of at least 2*server RTT time is recommended.
- // Returns true if we stopped, false otherwise.
- virtual bool Stop(int max_wait);
-
- private:
- SyncerThreadTimedStop(ClientCommandChannel* command_channel,
- syncable::DirectoryManager* mgr,
- ServerConnectionManager* connection_manager, AllStatus* all_status,
- ModelSafeWorker* model_safe_worker);
- virtual void ThreadMain();
-
- // We use this to track when our synthesized thread loop is active, so we can
- // timed-wait for it to become false. For this and only this (temporary)
- // implementation, we protect this variable using our parent lock_.
- bool in_thread_main_loop_;
-
- DISALLOW_COPY_AND_ASSIGN(SyncerThreadTimedStop);
-};
-
-} // namespace browser_sync
-
-#endif // CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_TIMED_STOP_H_ \ No newline at end of file
diff --git a/chrome/browser/sync/engine/syncer_thread_unittest.cc b/chrome/browser/sync/engine/syncer_thread_unittest.cc
index fa28f7f..6b758a7 100644
--- a/chrome/browser/sync/engine/syncer_thread_unittest.cc
+++ b/chrome/browser/sync/engine/syncer_thread_unittest.cc
@@ -7,158 +7,89 @@
#include <set>
#include <strstream>
-#include "base/command_line.h"
#include "base/scoped_ptr.h"
-#include "base/time.h"
-#include "chrome/browser/sync/engine/model_safe_worker.h"
#include "chrome/browser/sync/engine/syncer_thread.h"
-#include "chrome/browser/sync/engine/syncer_thread_timed_stop.h"
-#include "chrome/test/sync/engine/mock_server_connection.h"
-#include "chrome/test/sync/engine/test_directory_setter_upper.h"
#include "testing/gtest/include/gtest/gtest.h"
-using base::Time;
-using base::TimeDelta;
-
namespace browser_sync {
-typedef testing::Test SyncerThreadTest;
-
-class SyncerThreadWithSyncerTest : public testing::Test {
- public:
- SyncerThreadWithSyncerTest() {}
- virtual void SetUp() {
- metadb_.SetUp();
- connection_.reset(new MockConnectionManager(metadb_.manager(),
- metadb_.name()));
- allstatus_.reset(new AllStatus());
-
- syncer_thread_ = SyncerThreadFactory::Create(NULL, metadb_.manager(),
- connection_.get(), allstatus_.get(), new ModelSafeWorker());
-
- allstatus_->WatchSyncerThread(syncer_thread_);
- syncer_thread_->SetConnected(true);
- }
- virtual void TearDown() {
- syncer_thread_ = NULL;
- allstatus_.reset();
- connection_.reset();
- metadb_.TearDown();
- }
+class SyncerThreadTest : public testing::Test {
+ protected:
+ SyncerThreadTest() {}
+ virtual ~SyncerThreadTest() {}
+ virtual void SetUp() {}
+ virtual void TearDown() {}
- ManuallyOpenedTestDirectorySetterUpper* metadb() { return &metadb_; }
- MockConnectionManager* connection() { return connection_.get(); }
- SyncerThread* syncer_thread() { return syncer_thread_; }
- private:
- ManuallyOpenedTestDirectorySetterUpper metadb_;
- scoped_ptr<MockConnectionManager> connection_;
- scoped_ptr<AllStatus> allstatus_;
- scoped_refptr<SyncerThread> syncer_thread_;
- DISALLOW_COPY_AND_ASSIGN(SyncerThreadWithSyncerTest);
-};
-
-class SyncShareIntercept : public MockConnectionManager::MidCommitObserver {
- public:
- SyncShareIntercept() : sync_occured_(false, false) {}
- virtual ~SyncShareIntercept() {}
- virtual void Observe() {
- times_sync_occured_.push_back(Time::NowFromSystemTime());
- sync_occured_.Signal();
- }
- void WaitForSyncShare(int at_least_this_many, TimeDelta max_wait) {
- while (at_least_this_many-- > 0)
- sync_occured_.TimedWait(max_wait);
- }
- std::vector<Time> times_sync_occured() const {
- return times_sync_occured_;
- }
private:
- std::vector<Time> times_sync_occured_;
- base::WaitableEvent sync_occured_;
- DISALLOW_COPY_AND_ASSIGN(SyncShareIntercept);
+ DISALLOW_COPY_AND_ASSIGN(SyncerThreadTest);
};
TEST_F(SyncerThreadTest, Construction) {
- scoped_refptr<SyncerThread> syncer_thread(
- SyncerThreadFactory::Create(NULL, NULL, NULL, NULL, NULL));
-}
-
-TEST_F(SyncerThreadTest, StartStop) {
- scoped_refptr<SyncerThread> syncer_thread(
- SyncerThreadFactory::Create(NULL, NULL, NULL, NULL, NULL));
- EXPECT_TRUE(syncer_thread->Start());
- EXPECT_TRUE(syncer_thread->Stop(2000));
-
- // Do it again for good measure. I caught some bugs by adding this so
- // I would recommend keeping it.
- EXPECT_TRUE(syncer_thread->Start());
- EXPECT_TRUE(syncer_thread->Stop(2000));
+ SyncerThread syncer_thread(NULL, NULL, NULL, NULL, NULL);
}
TEST_F(SyncerThreadTest, CalculateSyncWaitTime) {
- scoped_refptr<SyncerThread> syncer_thread(
- SyncerThreadFactory::Create(NULL, NULL, NULL, NULL, NULL));
- syncer_thread->DisableIdleDetection();
-
- // Syncer_polling_interval_ is less than max poll interval.
- TimeDelta syncer_polling_interval = TimeDelta::FromSeconds(1);
+ SyncerThread syncer_thread(NULL, NULL, NULL, NULL, NULL);
+ syncer_thread.DisableIdleDetection();
- syncer_thread->SetSyncerPollingInterval(syncer_polling_interval);
+ // Syncer_polling_interval_ is less than max poll interval
+ int syncer_polling_interval = 1; // Needed since AssertionResult is not a
+ // friend of SyncerThread
+ syncer_thread.syncer_polling_interval_ = syncer_polling_interval;
// user_idle_ms is less than 10 * (syncer_polling_interval*1000).
- ASSERT_EQ(syncer_polling_interval.InMilliseconds(),
- syncer_thread->CalculateSyncWaitTime(1000, 0));
- ASSERT_EQ(syncer_polling_interval.InMilliseconds(),
- syncer_thread->CalculateSyncWaitTime(1000, 1));
+ ASSERT_EQ(syncer_polling_interval * 1000,
+ syncer_thread.CalculateSyncWaitTime(1000, 0));
+ ASSERT_EQ(syncer_polling_interval * 1000,
+ syncer_thread.CalculateSyncWaitTime(1000, 1));
// user_idle_ms is ge than 10 * (syncer_polling_interval*1000).
int last_poll_time = 2000;
ASSERT_LE(last_poll_time,
- syncer_thread->CalculateSyncWaitTime(last_poll_time, 10000));
+ syncer_thread.CalculateSyncWaitTime(last_poll_time, 10000));
ASSERT_GE(last_poll_time*3,
- syncer_thread->CalculateSyncWaitTime(last_poll_time, 10000));
+ syncer_thread.CalculateSyncWaitTime(last_poll_time, 10000));
ASSERT_LE(last_poll_time,
- syncer_thread->CalculateSyncWaitTime(last_poll_time, 100000));
+ syncer_thread.CalculateSyncWaitTime(last_poll_time, 100000));
ASSERT_GE(last_poll_time*3,
- syncer_thread->CalculateSyncWaitTime(last_poll_time, 100000));
+ syncer_thread.CalculateSyncWaitTime(last_poll_time, 100000));
// Maximum backoff time should be syncer_max_interval.
int near_threshold = SyncerThread::kDefaultMaxPollIntervalMs / 2 - 1;
int threshold = SyncerThread::kDefaultMaxPollIntervalMs;
int over_threshold = SyncerThread::kDefaultMaxPollIntervalMs + 1;
ASSERT_LE(near_threshold,
- syncer_thread->CalculateSyncWaitTime(near_threshold, 10000));
+ syncer_thread.CalculateSyncWaitTime(near_threshold, 10000));
ASSERT_GE(SyncerThread::kDefaultMaxPollIntervalMs,
- syncer_thread->CalculateSyncWaitTime(near_threshold, 10000));
+ syncer_thread.CalculateSyncWaitTime(near_threshold, 10000));
ASSERT_EQ(SyncerThread::kDefaultMaxPollIntervalMs,
- syncer_thread->CalculateSyncWaitTime(threshold, 10000));
+ syncer_thread.CalculateSyncWaitTime(threshold, 10000));
ASSERT_EQ(SyncerThread::kDefaultMaxPollIntervalMs,
- syncer_thread->CalculateSyncWaitTime(over_threshold, 10000));
+ syncer_thread.CalculateSyncWaitTime(over_threshold, 10000));
// Possible idle time must be capped by syncer_max_interval.
int over_sync_max_interval =
SyncerThread::kDefaultMaxPollIntervalMs + 1;
- syncer_polling_interval = TimeDelta::FromSeconds(
- over_sync_max_interval / 100); // so 1000* is right
- syncer_thread->SetSyncerPollingInterval(syncer_polling_interval);
- ASSERT_EQ(syncer_polling_interval.InSeconds() * 1000,
- syncer_thread->CalculateSyncWaitTime(1000, over_sync_max_interval));
- syncer_polling_interval = TimeDelta::FromSeconds(1);
- syncer_thread->SetSyncerPollingInterval(syncer_polling_interval);
+ syncer_polling_interval = over_sync_max_interval / 100; // so 1000* is right
+ syncer_thread.syncer_polling_interval_ = syncer_polling_interval;
+ ASSERT_EQ(syncer_polling_interval * 1000,
+ syncer_thread.CalculateSyncWaitTime(1000, over_sync_max_interval));
+ syncer_polling_interval = 1;
+ syncer_thread.syncer_polling_interval_ = syncer_polling_interval;
ASSERT_LE(last_poll_time,
- syncer_thread->CalculateSyncWaitTime(last_poll_time,
+ syncer_thread.CalculateSyncWaitTime(last_poll_time,
over_sync_max_interval));
ASSERT_GE(last_poll_time * 3,
- syncer_thread->CalculateSyncWaitTime(last_poll_time,
+ syncer_thread.CalculateSyncWaitTime(last_poll_time,
over_sync_max_interval));
}
TEST_F(SyncerThreadTest, CalculatePollingWaitTime) {
// Set up the environment.
int user_idle_milliseconds_param = 0;
- scoped_refptr<SyncerThread> syncer_thread(
- SyncerThreadFactory::Create(NULL, NULL, NULL, NULL, NULL));
- syncer_thread->DisableIdleDetection();
+
+ SyncerThread syncer_thread(NULL, NULL, NULL, NULL, NULL);
+ syncer_thread.DisableIdleDetection();
// Notifications disabled should result in a polling interval of
// kDefaultShortPollInterval.
@@ -169,7 +100,7 @@ TEST_F(SyncerThreadTest, CalculatePollingWaitTime) {
// No work and no backoff.
ASSERT_EQ(SyncerThread::kDefaultShortPollIntervalSeconds,
- syncer_thread->CalculatePollingWaitTime(
+ syncer_thread.CalculatePollingWaitTime(
status,
0,
&user_idle_milliseconds_param,
@@ -179,7 +110,7 @@ TEST_F(SyncerThreadTest, CalculatePollingWaitTime) {
// In this case the continue_sync_cycle is turned off.
continue_sync_cycle_param = true;
ASSERT_EQ(SyncerThread::kDefaultShortPollIntervalSeconds,
- syncer_thread->CalculatePollingWaitTime(
+ syncer_thread.CalculatePollingWaitTime(
status,
0,
&user_idle_milliseconds_param,
@@ -200,7 +131,7 @@ TEST_F(SyncerThreadTest, CalculatePollingWaitTime) {
// No work and no backoff.
ASSERT_EQ(SyncerThread::kDefaultLongPollIntervalSeconds,
- syncer_thread->CalculatePollingWaitTime(
+ syncer_thread.CalculatePollingWaitTime(
status,
0,
&user_idle_milliseconds_param,
@@ -210,7 +141,7 @@ TEST_F(SyncerThreadTest, CalculatePollingWaitTime) {
// In this case the continue_sync_cycle is turned off.
continue_sync_cycle_param = true;
ASSERT_EQ(SyncerThread::kDefaultLongPollIntervalSeconds,
- syncer_thread->CalculatePollingWaitTime(
+ syncer_thread.CalculatePollingWaitTime(
status,
0,
&user_idle_milliseconds_param,
@@ -231,7 +162,7 @@ TEST_F(SyncerThreadTest, CalculatePollingWaitTime) {
status.updates_received = 0;
bool continue_sync_cycle_param = false;
- ASSERT_LE(0, syncer_thread->CalculatePollingWaitTime(
+ ASSERT_LE(0, syncer_thread.CalculatePollingWaitTime(
status,
0,
&user_idle_milliseconds_param,
@@ -239,19 +170,19 @@ TEST_F(SyncerThreadTest, CalculatePollingWaitTime) {
ASSERT_TRUE(continue_sync_cycle_param);
continue_sync_cycle_param = false;
- ASSERT_GE(3, syncer_thread->CalculatePollingWaitTime(
+ ASSERT_GE(3, syncer_thread.CalculatePollingWaitTime(
status,
0,
&user_idle_milliseconds_param,
&continue_sync_cycle_param));
ASSERT_TRUE(continue_sync_cycle_param);
- ASSERT_LE(0, syncer_thread->CalculatePollingWaitTime(
+ ASSERT_LE(0, syncer_thread.CalculatePollingWaitTime(
status,
0,
&user_idle_milliseconds_param,
&continue_sync_cycle_param));
- ASSERT_GE(2, syncer_thread->CalculatePollingWaitTime(
+ ASSERT_GE(2, syncer_thread.CalculatePollingWaitTime(
status,
0,
&user_idle_milliseconds_param,
@@ -260,7 +191,7 @@ TEST_F(SyncerThreadTest, CalculatePollingWaitTime) {
status.updates_received = 1;
ASSERT_EQ(SyncerThread::kDefaultShortPollIntervalSeconds,
- syncer_thread->CalculatePollingWaitTime(
+ syncer_thread.CalculatePollingWaitTime(
status,
10,
&user_idle_milliseconds_param,
@@ -273,7 +204,7 @@ TEST_F(SyncerThreadTest, CalculatePollingWaitTime) {
status.unsynced_count = 1;
bool continue_sync_cycle_param = false;
- ASSERT_LE(0, syncer_thread->CalculatePollingWaitTime(
+ ASSERT_LE(0, syncer_thread.CalculatePollingWaitTime(
status,
0,
&user_idle_milliseconds_param,
@@ -281,7 +212,7 @@ TEST_F(SyncerThreadTest, CalculatePollingWaitTime) {
ASSERT_TRUE(continue_sync_cycle_param);
continue_sync_cycle_param = false;
- ASSERT_GE(2, syncer_thread->CalculatePollingWaitTime(
+ ASSERT_GE(2, syncer_thread.CalculatePollingWaitTime(
status,
0,
&user_idle_milliseconds_param,
@@ -290,7 +221,7 @@ TEST_F(SyncerThreadTest, CalculatePollingWaitTime) {
status.unsynced_count = 0;
ASSERT_EQ(SyncerThread::kDefaultShortPollIntervalSeconds,
- syncer_thread->CalculatePollingWaitTime(
+ syncer_thread.CalculatePollingWaitTime(
status,
4,
&user_idle_milliseconds_param,
@@ -306,7 +237,7 @@ TEST_F(SyncerThreadTest, CalculatePollingWaitTime) {
// Expect move from default polling interval to exponential backoff due to
// unsynced_count != 0.
- ASSERT_LE(0, syncer_thread->CalculatePollingWaitTime(
+ ASSERT_LE(0, syncer_thread.CalculatePollingWaitTime(
status,
3600,
&user_idle_milliseconds_param,
@@ -314,7 +245,7 @@ TEST_F(SyncerThreadTest, CalculatePollingWaitTime) {
ASSERT_TRUE(continue_sync_cycle_param);
continue_sync_cycle_param = false;
- ASSERT_GE(2, syncer_thread->CalculatePollingWaitTime(
+ ASSERT_GE(2, syncer_thread.CalculatePollingWaitTime(
status,
3600,
&user_idle_milliseconds_param,
@@ -322,12 +253,12 @@ TEST_F(SyncerThreadTest, CalculatePollingWaitTime) {
ASSERT_TRUE(continue_sync_cycle_param);
// Expect exponential backoff.
- ASSERT_LE(2, syncer_thread->CalculatePollingWaitTime(
+ ASSERT_LE(2, syncer_thread.CalculatePollingWaitTime(
status,
2,
&user_idle_milliseconds_param,
&continue_sync_cycle_param));
- ASSERT_GE(6, syncer_thread->CalculatePollingWaitTime(
+ ASSERT_GE(6, syncer_thread.CalculatePollingWaitTime(
status,
2,
&user_idle_milliseconds_param,
@@ -337,7 +268,7 @@ TEST_F(SyncerThreadTest, CalculatePollingWaitTime) {
// A nudge resets the continue_sync_cycle_param value, so our backoff
// should return to the minimum.
continue_sync_cycle_param = false;
- ASSERT_LE(0, syncer_thread->CalculatePollingWaitTime(
+ ASSERT_LE(0, syncer_thread.CalculatePollingWaitTime(
status,
3600,
&user_idle_milliseconds_param,
@@ -345,7 +276,7 @@ TEST_F(SyncerThreadTest, CalculatePollingWaitTime) {
ASSERT_TRUE(continue_sync_cycle_param);
continue_sync_cycle_param = false;
- ASSERT_GE(2, syncer_thread->CalculatePollingWaitTime(
+ ASSERT_GE(2, syncer_thread.CalculatePollingWaitTime(
status,
3600,
&user_idle_milliseconds_param,
@@ -355,7 +286,7 @@ TEST_F(SyncerThreadTest, CalculatePollingWaitTime) {
// Setting unsynced_count = 0 returns us to the default polling interval.
status.unsynced_count = 0;
ASSERT_EQ(SyncerThread::kDefaultShortPollIntervalSeconds,
- syncer_thread->CalculatePollingWaitTime(
+ syncer_thread.CalculatePollingWaitTime(
status,
4,
&user_idle_milliseconds_param,
@@ -364,67 +295,4 @@ TEST_F(SyncerThreadTest, CalculatePollingWaitTime) {
}
}
-TEST_F(SyncerThreadWithSyncerTest, Polling) {
- SyncShareIntercept interceptor;
- connection()->SetMidCommitObserver(&interceptor);
-
- const TimeDelta poll_interval = TimeDelta::FromSeconds(1);
- syncer_thread()->SetSyncerShortPollInterval(poll_interval);
- EXPECT_TRUE(syncer_thread()->Start());
-
- // Calling Open() should cause the SyncerThread to create a Syncer.
- metadb()->Open();
-
- TimeDelta two_polls = poll_interval + poll_interval;
- // We could theoretically return immediately from the wait if the interceptor
- // was already signaled for a SyncShare (the first one comes quick).
- interceptor.WaitForSyncShare(1, two_polls);
- EXPECT_FALSE(interceptor.times_sync_occured().empty());
-
- // Wait for at least 2 more SyncShare operations.
- interceptor.WaitForSyncShare(2, two_polls);
- EXPECT_TRUE(syncer_thread()->Stop(2000));
-
- // Now analyze the run.
- std::vector<Time> data = interceptor.times_sync_occured();
-
- EXPECT_GE(data.size(), static_cast<unsigned int>(3));
- for (unsigned int i = 0; i < data.size() - 1; i++) {
- Time optimal_next_sync = data[i] + poll_interval;
- // The pthreads impl uses a different time impl and is slightly (~900usecs)
- // off, so this expectation can fail with --syncer-thread-pthreads.
- EXPECT_TRUE(data[i + 1] >= optimal_next_sync)
- << "difference is "
- << (data[i + 1] - optimal_next_sync).InMicroseconds() << " usecs. "
- << "~900usec delta is OK with --syncer-thread-pthreads";
- // This should be reliable, as there are no blocking or I/O operations
- // except the explicit 2 second wait, so if it takes longer than this
- // there is a problem.
- EXPECT_TRUE(data[i + 1] < optimal_next_sync + poll_interval);
- }
-}
-
-TEST_F(SyncerThreadWithSyncerTest, Nudge) {
- SyncShareIntercept interceptor;
- connection()->SetMidCommitObserver(&interceptor);
- // We don't want a poll to happen during this test (except the first one).
- const TimeDelta poll_interval = TimeDelta::FromMinutes(5);
- syncer_thread()->SetSyncerShortPollInterval(poll_interval);
- EXPECT_TRUE(syncer_thread()->Start());
- metadb()->Open();
- interceptor.WaitForSyncShare(1, poll_interval + poll_interval);
-
- EXPECT_EQ(static_cast<unsigned int>(1),
- interceptor.times_sync_occured().size());
- // The SyncerThread should be waiting for the poll now. Nudge it to sync
- // immediately (5ms).
- syncer_thread()->NudgeSyncer(5, SyncerThread::kUnknown);
- interceptor.WaitForSyncShare(1, TimeDelta::FromSeconds(1));
- EXPECT_EQ(static_cast<unsigned int>(2),
- interceptor.times_sync_occured().size());
-
- // SyncerThread should be waiting again. Signal it to stop.
- EXPECT_TRUE(syncer_thread()->Stop(2000));
-}
-
} // namespace browser_sync
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 0587c15..80c834b 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -4589,7 +4589,6 @@
'../third_party/libjingle/libjingle.gyp:libjingle',
'../third_party/protobuf2/protobuf.gyp:protobuf',
'../third_party/sqlite/sqlite.gyp:sqlite',
- 'common',
'notifier',
'sync',
],
@@ -6568,10 +6567,6 @@
'browser/sync/engine/syncer_status.h',
'browser/sync/engine/syncer_thread.cc',
'browser/sync/engine/syncer_thread.h',
- 'browser/sync/engine/syncer_thread_timed_stop.cc',
- 'browser/sync/engine/syncer_thread_timed_stop.h',
- 'browser/sync/engine/syncer_thread_pthreads.cc',
- 'browser/sync/engine/syncer_thread_pthreads.h',
'browser/sync/engine/syncer_types.h',
'browser/sync/engine/syncer_util.cc',
'browser/sync/engine/syncer_util.h',
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 14aea58..075a350 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -378,16 +378,6 @@ const wchar_t kEnableFastback[] = L"enable-fastback";
// Enable syncing bookmarks to a Google Account.
const wchar_t kEnableSync[] = L"enable-sync";
-// Use the SyncerThread implementation that matches up with the old pthread
-// impl semantics, but using Chrome synchronization primitives. The only
-// difference between this and the default is that we now have no timeout on
-// Stop(). Should only use if you experience problems with the default.
-const wchar_t kSyncerThreadTimedStop[] = L"syncer-thread-timed-stop";
-
-// Use the old pthreads SyncerThread implementation.
-// Should only use if you experience problems with the default.
-const wchar_t kSyncerThreadPthreads[] = L"syncer-thread-pthreads";
-
// Enable support for SDCH filtering (dictionary based expansion of content).
// Optional argument is *the* only domain name that will have SDCH suppport.
// Default is "-enable-sdch" to advertise SDCH on all domains.
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index 9ed753c..f031399 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -140,8 +140,6 @@ extern const wchar_t kGearsPluginPathOverride[];
extern const wchar_t kEnableFastback[];
extern const wchar_t kEnableSync[];
-extern const wchar_t kSyncerThreadTimedStop[];
-extern const wchar_t kSyncerThreadPthreads[];
extern const wchar_t kSdchFilter[];
diff --git a/chrome/test/sync/engine/mock_server_connection.cc b/chrome/test/sync/engine/mock_server_connection.cc
index c4595bd..bd3d90f 100644
--- a/chrome/test/sync/engine/mock_server_connection.cc
+++ b/chrome/test/sync/engine/mock_server_connection.cc
@@ -25,7 +25,6 @@ using sync_pb::CommitResponse_EntryResponse;
using sync_pb::GetUpdatesMessage;
using sync_pb::SyncEntity;
using syncable::DirectoryManager;
-using syncable::ScopedDirLookup;
using syncable::WriteTransaction;
MockConnectionManager::MockConnectionManager(DirectoryManager* dirmgr,
@@ -39,13 +38,12 @@ MockConnectionManager::MockConnectionManager(DirectoryManager* dirmgr,
client_stuck_(false),
commit_time_rename_prepended_string_(""),
fail_next_postbuffer_(false),
- directory_manager_(dirmgr),
- directory_name_(name),
+ directory_(dirmgr, name),
mid_commit_callback_function_(NULL),
- mid_commit_observer_(NULL),
client_command_(NULL),
next_position_in_parent_(2) {
server_reachable_ = true;
+ CHECK(directory_.good());
};
MockConnectionManager::~MockConnectionManager() {
@@ -62,18 +60,9 @@ void MockConnectionManager::SetMidCommitCallbackFunction(
mid_commit_callback_function_ = callback;
}
-void MockConnectionManager::SetMidCommitObserver(
- MockConnectionManager::MidCommitObserver* observer) {
- mid_commit_observer_ = observer;
-}
-
bool MockConnectionManager::PostBufferToPath(const PostBufferParams* params,
const string& path,
const string& auth_token) {
-
- ScopedDirLookup directory(directory_manager_, directory_name_);
- CHECK(directory.good());
-
ClientToServerMessage post;
CHECK(post.ParseFromString(params->buffer_in));
client_stuck_ = post.sync_problem_detected();
@@ -84,7 +73,7 @@ bool MockConnectionManager::PostBufferToPath(const PostBufferParams* params,
// network. As we can't test this we do the next best thing and hang here
// when there's an issue.
{
- WriteTransaction wt(directory, syncable::UNITTEST, __FILE__, __LINE__);
+ WriteTransaction wt(directory_, syncable::UNITTEST, __FILE__, __LINE__);
}
if (fail_next_postbuffer_) {
fail_next_postbuffer_ = false;
@@ -116,12 +105,9 @@ bool MockConnectionManager::PostBufferToPath(const PostBufferParams* params,
}
response.SerializeToString(params->buffer_out);
if (mid_commit_callback_function_) {
- if (mid_commit_callback_function_(directory))
+ if (mid_commit_callback_function_(directory_))
mid_commit_callback_function_ = 0;
}
- if (mid_commit_observer_) {
- mid_commit_observer_->Observe();
- }
return result;
}
diff --git a/chrome/test/sync/engine/mock_server_connection.h b/chrome/test/sync/engine/mock_server_connection.h
index 8c0cca7..e5573e0 100644
--- a/chrome/test/sync/engine/mock_server_connection.h
+++ b/chrome/test/sync/engine/mock_server_connection.h
@@ -31,10 +31,6 @@ class MockConnectionManager : public browser_sync::ServerConnectionManager {
// activity would normally take place. This aids simulation of race
// conditions.
typedef bool (*TestCallbackFunction)(syncable::Directory* dir);
- class MidCommitObserver {
- public:
- virtual void Observe() = 0;
- };
MockConnectionManager(syncable::DirectoryManager* dirmgr, PathString name);
virtual ~MockConnectionManager();
@@ -49,7 +45,6 @@ class MockConnectionManager : public browser_sync::ServerConnectionManager {
// Control of commit response.
void SetMidCommitCallbackFunction(TestCallbackFunction callback);
- void SetMidCommitObserver(MidCommitObserver* observer);
// Set this if you want commit to perform commit time rename. Will request
// that the client renames all commited entries, prepending this string.
@@ -182,13 +177,11 @@ class MockConnectionManager : public browser_sync::ServerConnectionManager {
bool fail_next_postbuffer_;
// Our directory.
- syncable::DirectoryManager* directory_manager_;
- PathString directory_name_;
+ syncable::ScopedDirLookup directory_;
// The updates we'll return to the next request.
sync_pb::GetUpdatesResponse updates_;
TestCallbackFunction mid_commit_callback_function_;
- MidCommitObserver* mid_commit_observer_;
scoped_ptr<sync_pb::ClientCommand> client_command_;
diff --git a/chrome/test/sync/engine/test_directory_setter_upper.cc b/chrome/test/sync/engine/test_directory_setter_upper.cc
index 0a7b32d..468875a 100644
--- a/chrome/test/sync/engine/test_directory_setter_upper.cc
+++ b/chrome/test/sync/engine/test_directory_setter_upper.cc
@@ -20,15 +20,12 @@ TestDirectorySetterUpper::TestDirectorySetterUpper() : name_(PSTR("Test")) {}
TestDirectorySetterUpper::~TestDirectorySetterUpper() {}
-void TestDirectorySetterUpper::Init() {
+void TestDirectorySetterUpper::SetUp() {
PathString test_data_dir_ = PSTR(".");
manager_.reset(new DirectoryManager(test_data_dir_));
file_path_ = manager_->GetSyncDataDatabasePath();
PathRemove(file_path_.c_str());
-}
-void TestDirectorySetterUpper::SetUp() {
- Init();
ASSERT_TRUE(manager()->Open(name()));
}
@@ -67,19 +64,4 @@ void TestDirectorySetterUpper::RunInvariantCheck(const ScopedDirLookup& dir) {
}
}
-void ManuallyOpenedTestDirectorySetterUpper::SetUp() {
- Init();
-}
-
-void ManuallyOpenedTestDirectorySetterUpper::Open() {
- ASSERT_TRUE(manager()->Open(name()));
- was_opened_ = true;
-}
-
-void ManuallyOpenedTestDirectorySetterUpper::TearDown() {
- if (was_opened_) {
- TestDirectorySetterUpper::TearDown();
- }
-}
-
} // namespace browser_sync
diff --git a/chrome/test/sync/engine/test_directory_setter_upper.h b/chrome/test/sync/engine/test_directory_setter_upper.h
index 0cfa3e6..0cac7e1 100644
--- a/chrome/test/sync/engine/test_directory_setter_upper.h
+++ b/chrome/test/sync/engine/test_directory_setter_upper.h
@@ -44,23 +44,20 @@ namespace browser_sync {
class TestDirectorySetterUpper {
public:
TestDirectorySetterUpper();
- virtual ~TestDirectorySetterUpper();
+ ~TestDirectorySetterUpper();
// Create a DirectoryManager instance and use it to open the directory.
// Clears any existing database backing files that might exist on disk.
- virtual void SetUp();
+ void SetUp();
// Undo everything done by SetUp(): close the directory and delete the
// backing files. Before closing the directory, this will run the directory
// invariant checks and perform the SaveChanges action on the directory.
- virtual void TearDown();
+ void TearDown();
syncable::DirectoryManager* manager() const { return manager_.get(); }
const PathString& name() const { return name_; }
- protected:
- virtual void Init();
-
private:
void RunInvariantCheck(const syncable::ScopedDirLookup& dir);
@@ -69,19 +66,6 @@ class TestDirectorySetterUpper {
PathString file_path_;
};
-// A variant of the above where SetUp does not actually open the directory.
-// You must manually invoke Open(). This is useful if you are writing a test
-// that depends on the DirectoryManager::OPENED event.
-class ManuallyOpenedTestDirectorySetterUpper : public TestDirectorySetterUpper {
- public:
- ManuallyOpenedTestDirectorySetterUpper() : was_opened_(false) {}
- virtual void SetUp();
- virtual void TearDown();
- void Open();
- private:
- bool was_opened_;
-};
-
} // namespace browser_sync
#endif // CHROME_TEST_SYNC_ENGINE_TEST_DIRECTORY_SETTER_UPPER_H_