summaryrefslogtreecommitdiffstats
path: root/chrome/browser/sync/engine/syncer_thread.h
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/sync/engine/syncer_thread.h')
-rw-r--r--chrome/browser/sync/engine/syncer_thread.h575
1 files changed, 299 insertions, 276 deletions
diff --git a/chrome/browser/sync/engine/syncer_thread.h b/chrome/browser/sync/engine/syncer_thread.h
index 11fee16..d270f14 100644
--- a/chrome/browser/sync/engine/syncer_thread.h
+++ b/chrome/browser/sync/engine/syncer_thread.h
@@ -3,175 +3,74 @@
// 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_
#pragma once
-#include "base/callback.h"
-#include "base/memory/linked_ptr.h"
+#include <list>
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/gtest_prod_util.h"
+#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/observer_list.h"
-#include "base/task.h"
+#include "base/synchronization/condition_variable.h"
#include "base/threading/thread.h"
#include "base/time.h"
-#include "base/timer.h"
-#include "chrome/browser/sync/engine/nudge_source.h"
-#include "chrome/browser/sync/engine/polling_constants.h"
-#include "chrome/browser/sync/engine/syncer.h"
-#include "chrome/browser/sync/syncable/model_type_payload_map.h"
-#include "chrome/browser/sync/engine/net/server_connection_manager.h"
+#include "base/synchronization/waitable_event.h"
+#include "chrome/browser/sync/engine/syncer_types.h"
#include "chrome/browser/sync/sessions/sync_session.h"
-#include "chrome/browser/sync/sessions/sync_session_context.h"
+#include "chrome/browser/sync/syncable/model_type.h"
+#include "chrome/browser/sync/syncable/model_type_payload_map.h"
+#include "chrome/common/deprecated/event_sys-inl.h"
+
+#if defined(OS_LINUX)
+#include "chrome/browser/sync/engine/idle_query_linux.h"
+#endif
+
+class EventListenerHookup;
namespace browser_sync {
+class ModelSafeWorker;
+class ServerConnectionManager;
+class Syncer;
+class URLFactory;
struct ServerConnectionEvent;
-class SyncerThread : public sessions::SyncSession::Delegate,
- public ServerConnectionEventListener {
+class SyncerThread : public base::RefCountedThreadSafe<SyncerThread>,
+ public sessions::SyncSession::Delegate {
+ FRIEND_TEST_ALL_PREFIXES(SyncerThreadTest, CalculateSyncWaitTime);
+ FRIEND_TEST_ALL_PREFIXES(SyncerThreadTest, CalculatePollingWaitTime);
+ FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, Polling);
+ FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, Nudge);
+ FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, NudgeWithDataTypes);
+ FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest,
+ NudgeWithDataTypesCoalesced);
+ FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, NudgeWithPayloads);
+ FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest,
+ NudgeWithPayloadsCoalesced);
+ FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, Throttling);
+ FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, AuthInvalid);
+ FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, Pause);
+ FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, StartWhenNotConnected);
+ FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, PauseWhenNotConnected);
+ FRIEND_TEST_ALL_PREFIXES(SyncerThreadWithSyncerTest, StopSyncPermanently);
+ friend class SyncerThreadWithSyncerTest;
+ friend class SyncerThreadFactory;
public:
- enum Mode {
- // In this mode, the thread only performs configuration tasks. This is
- // designed to make the case where we want to download updates for a
- // specific type only, and not continue syncing until we are moved into
- // normal mode.
- CONFIGURATION_MODE,
- // Resumes polling and allows nudges, drops configuration tasks. Runs
- // through entire sync cycle.
- NORMAL_MODE,
- };
-
- // Takes ownership of both |context| and |syncer|.
- SyncerThread(sessions::SyncSessionContext* context, Syncer* syncer);
- virtual ~SyncerThread();
-
- typedef Callback0::Type ModeChangeCallback;
-
- // Change the mode of operation.
- // We don't use a lock when changing modes, so we won't cause currently
- // scheduled jobs to adhere to the new mode. We could protect it, but it
- // doesn't buy very much as a) a session could already be in progress and it
- // will continue no matter what, b) the scheduled sessions already contain
- // all their required state and won't be affected by potential change at
- // higher levels (i.e. the registrar), and c) we service tasks FIFO, so once
- // the mode changes all future jobs will be run against the updated mode.
- // If supplied, |callback| will be invoked when the mode has been
- // changed to |mode| *from the SyncerThread*, and not from the caller
- // thread.
- void Start(Mode mode, ModeChangeCallback* callback);
-
- // Joins on the thread as soon as possible (currently running session
- // completes).
- void Stop();
-
- // The meat and potatoes.
- void ScheduleNudge(const base::TimeDelta& delay, NudgeSource source,
- const syncable::ModelTypeBitSet& types,
- const tracked_objects::Location& nudge_location);
- void ScheduleNudgeWithPayloads(
- const base::TimeDelta& delay, NudgeSource source,
- const syncable::ModelTypePayloadMap& types_with_payloads,
- const tracked_objects::Location& nudge_location);
- void ScheduleConfig(const syncable::ModelTypeBitSet& types);
- void ScheduleClearUserData();
-
- // Change status of notifications in the SyncSessionContext.
- void set_notifications_enabled(bool notifications_enabled);
-
- // DDOS avoidance function. Calculates how long we should wait before trying
- // again after a failed sync attempt, where the last delay was |base_delay|.
- // TODO(tim): Look at URLRequestThrottlerEntryInterface.
- static base::TimeDelta GetRecommendedDelay(const base::TimeDelta& base_delay);
-
- // SyncSession::Delegate implementation.
- virtual void OnSilencedUntil(const base::TimeTicks& silenced_until);
- virtual bool IsSyncingCurrentlySilenced();
- virtual void OnReceivedShortPollIntervalUpdate(
- const base::TimeDelta& new_interval);
- virtual void OnReceivedLongPollIntervalUpdate(
- const base::TimeDelta& new_interval);
- virtual void OnShouldStopSyncingPermanently();
-
- // ServerConnectionEventListener implementation.
- // TODO(tim): schedule a nudge when valid connection detected? in 1 minute?
- virtual void OnServerConnectionEvent(const ServerConnectionEvent2& event);
-
- private:
- enum JobProcessDecision {
- // Indicates we should continue with the current job.
- CONTINUE,
- // Indicates that we should save it to be processed later.
- SAVE,
- // Indicates we should drop this job.
- DROP,
- };
-
- struct SyncSessionJob {
- // An enum used to describe jobs for scheduling purposes.
- enum SyncSessionJobPurpose {
- // Our poll timer schedules POLL jobs periodically based on a server
- // assigned poll interval.
- POLL,
- // A nudge task can come from a variety of components needing to force
- // a sync. The source is inferable from |session.source()|.
- NUDGE,
- // The user invoked a function in the UI to clear their entire account
- // and stop syncing (globally).
- CLEAR_USER_DATA,
- // Typically used for fetching updates for a subset of the enabled types
- // during initial sync or reconfiguration. We don't run all steps of
- // the sync cycle for these (e.g. CleanupDisabledTypes is skipped).
- CONFIGURATION,
- };
- SyncSessionJob();
- SyncSessionJob(SyncSessionJobPurpose purpose, base::TimeTicks start,
- linked_ptr<sessions::SyncSession> session, bool is_canary_job,
- const tracked_objects::Location& nudge_location);
- ~SyncSessionJob();
- SyncSessionJobPurpose purpose;
- base::TimeTicks scheduled_start;
- linked_ptr<sessions::SyncSession> session;
- bool is_canary_job;
-
- // This is the location the nudge came from. used for debugging purpose.
- // In case of multiple nudges getting coalesced this stores the first nudge
- // that came in.
- tracked_objects::Location nudge_location;
- };
- friend class SyncerThread2Test;
- friend class SyncerThread2WhiteboxTest;
-
- FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest,
- DropNudgeWhileExponentialBackOff);
- FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, SaveNudge);
- FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, ContinueNudge);
- FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, DropPoll);
- FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, ContinuePoll);
- FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest, ContinueConfiguration);
- FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest,
- SaveConfigurationWhileThrottled);
- FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest,
- SaveNudgeWhileThrottled);
- FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest,
- ContinueClearUserDataUnderAllCircumstances);
- FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest,
- ContinueCanaryJobConfig);
- FRIEND_TEST_ALL_PREFIXES(SyncerThread2WhiteboxTest,
- ContinueNudgeWhileExponentialBackOff);
-
- // A component used to get time delays associated with exponential backoff.
- // Encapsulated into a class to facilitate testing.
- class DelayProvider {
- public:
- DelayProvider();
- virtual base::TimeDelta GetDelay(const base::TimeDelta& last_delay);
- virtual ~DelayProvider();
- private:
- DISALLOW_COPY_AND_ASSIGN(DelayProvider);
- };
-
+ // Encapsulates the parameters that make up an interval on which the
+ // syncer thread is sleeping.
struct WaitInterval {
enum Mode {
+ // A wait interval whose duration has not been affected by exponential
+ // backoff. The base case for exponential backoff falls in to this case
+ // (e.g when the exponent is 1). So far, we don't need a separate case.
+ // NORMAL intervals are not nudge-rate limited.
+ NORMAL,
// A wait interval whose duration has been affected by exponential
// backoff.
// EXPONENTIAL_BACKOFF intervals are nudge-rate limited to 1 per interval.
@@ -180,162 +79,286 @@ class SyncerThread : public sessions::SyncSession::Delegate,
// during such an interval.
THROTTLED,
};
- WaitInterval();
- ~WaitInterval();
Mode mode;
-
- // This bool is set to true if we have observed a nudge during this
+ // This bool is set to true if we have observed a nudge during during this
// interval and mode == EXPONENTIAL_BACKOFF.
- bool had_nudge;
- base::TimeDelta length;
- base::OneShotTimer<SyncerThread> timer;
-
- // Configure jobs are saved only when backing off or throttling. So we
- // expose the pointer here.
- scoped_ptr<SyncSessionJob> pending_configure_job;
- WaitInterval(Mode mode, base::TimeDelta length);
- };
-
- // Helper to assemble a job and post a delayed task to sync.
- void ScheduleSyncSessionJob(
- const base::TimeDelta& delay,
- SyncSessionJob::SyncSessionJobPurpose purpose,
- sessions::SyncSession* session,
- const tracked_objects::Location& nudge_location);
+ bool had_nudge_during_backoff;
+ base::TimeDelta poll_delta; // The wait duration until the next poll.
- // Invoke the Syncer to perform a sync.
- void DoSyncSessionJob(const SyncSessionJob& job);
-
- // Called after the Syncer has performed the sync represented by |job|, to
- // reset our state.
- void FinishSyncSessionJob(const SyncSessionJob& job);
-
- // Record important state that might be needed in future syncs, such as which
- // data types may require cleanup.
- void UpdateCarryoverSessionState(const SyncSessionJob& old_job);
-
- // Helper to FinishSyncSessionJob to schedule the next sync operation.
- void ScheduleNextSync(const SyncSessionJob& old_job);
+ WaitInterval() : mode(NORMAL), had_nudge_during_backoff(false) { }
+ };
- // Helper to configure polling intervals. Used by Start and ScheduleNextSync.
- void AdjustPolling(const SyncSessionJob* old_job);
+ enum NudgeSource {
+ kUnknown = 0,
+ kNotification,
+ kLocal,
+ kContinuation,
+ kClearPrivateData
+ };
+ // Server can overwrite these values via client commands.
+ // Standard short poll. This is used when XMPP is off.
+ static const int kDefaultShortPollIntervalSeconds;
+ // Long poll is used when XMPP is on.
+ static const int kDefaultLongPollIntervalSeconds;
+ // 30 minutes by default. If exponential backoff kicks in, this is the
+ // longest possible poll interval.
+ static const int kDefaultMaxPollIntervalMs;
+ // Maximum interval for exponential backoff.
+ static const int kMaxBackoffSeconds;
+
+ explicit SyncerThread(sessions::SyncSessionContext* context);
+ virtual ~SyncerThread();
- // Helper to ScheduleNextSync in case of consecutive sync errors.
- void HandleConsecutiveContinuationError(const SyncSessionJob& old_job);
+ virtual void WatchConnectionManager(ServerConnectionManager* conn_mgr);
+
+ // 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. |max_wait| doesn't do anything in this version.
+ virtual bool Stop(int max_wait);
+
+ // Request that the thread pauses. Returns false if the request can
+ // not be completed (e.g. the thread is not running). When the
+ // thread actually pauses, a SyncEngineEvent::PAUSED event notification
+ // will be sent to the relay channel.
+ virtual bool RequestPause();
+
+ // Request that the thread resumes from pause. Returns false if the
+ // request can not be completed (e.g. the thread is not running or
+ // is not currently paused). When the thread actually resumes, a
+ // SyncEngineEvent::RESUMED event notification will be sent to the relay
+ // channel.
+ virtual bool RequestResume();
+
+ // 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 void NudgeSyncer(int milliseconds_from_now, NudgeSource source);
+
+ // Same as |NudgeSyncer|, but supports tracking the datatypes that caused
+ // the nudge to occur.
+ virtual void NudgeSyncerWithDataTypes(
+ int milliseconds_from_now,
+ NudgeSource source,
+ const syncable::ModelTypeBitSet& model_types);
+
+ // Same as |NudgeSyncer|, but supports including a payload for passing on to
+ // the download updates command. Datatypes with payloads are also considered
+ // to have caused a nudged to occur and treated accordingly.
+ virtual void NudgeSyncerWithPayloads(
+ int milliseconds_from_now,
+ NudgeSource source,
+ const syncable::ModelTypePayloadMap& model_types_with_payloads);
+
+ void SetNotificationsEnabled(bool notifications_enabled);
+
+ // Call this when a directory is opened
+ void CreateSyncer(const std::string& dirname);
+
+ // DDOS avoidance function. The argument and return value is in seconds
+ static int GetRecommendedDelaySeconds(int base_delay_seconds);
+
+ protected:
+ virtual void ThreadMain();
+ void ThreadMainLoop();
+
+ virtual void SetConnected(bool connected);
+
+ virtual void SetSyncerPollingInterval(base::TimeDelta interval);
+ virtual void SetSyncerShortPollInterval(base::TimeDelta interval);
+
+ // 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_;
+
+ // Handle of the running thread.
+ base::Thread thread_;
- // Determines if it is legal to run |job| by checking current
- // operational mode, backoff or throttling, freshness
- // (so we don't make redundant syncs), and connection.
- bool ShouldRunJob(const SyncSessionJob& job);
+ // Fields that are modified / accessed by multiple threads go in this struct
+ // for clarity and explicitness.
+ struct ProtectedFields {
+ ProtectedFields();
+ ~ProtectedFields();
- // Decide whether we should CONTINUE, SAVE or DROP the job.
- JobProcessDecision DecideOnJob(const SyncSessionJob& job);
+ // False when we want to stop the thread.
+ bool stop_syncer_thread_;
- // Decide on whether to CONTINUE, SAVE or DROP the job when we are in
- // backoff mode.
- JobProcessDecision DecideWhileInWaitInterval(const SyncSessionJob& job);
+ // True when a pause was requested.
+ bool pause_requested_;
- // Saves the job for future execution. Note: It drops all the poll jobs.
- void SaveJob(const SyncSessionJob& job);
+ // True when the thread is paused.
+ bool paused_;
- // Coalesces the current job with the pending nudge.
- void InitOrCoalescePendingJob(const SyncSessionJob& job);
+ Syncer* syncer_;
- // 'Impl' here refers to real implementation of public functions, running on
- // |thread_|.
- void StartImpl(Mode mode, linked_ptr<ModeChangeCallback> callback);
- void ScheduleNudgeImpl(
- const base::TimeDelta& delay,
- sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source,
- const syncable::ModelTypePayloadMap& types_with_payloads,
- bool is_canary_job, const tracked_objects::Location& nudge_location);
- void ScheduleConfigImpl(const ModelSafeRoutingInfo& routing_info,
- const std::vector<ModelSafeWorker*>& workers,
- const sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source);
- void ScheduleClearUserDataImpl();
+ // State of the server connection.
+ bool connected_;
- // Returns true if the client is currently in exponential backoff.
- bool IsBackingOff() const;
+ // kUnknown if there is no pending nudge. (Theoretically, there
+ // could be a pending nudge of type kUnknown, so it's better to
+ // check pending_nudge_time_.)
+ NudgeSource pending_nudge_source_;
- // Helper to signal all listeners registered with |session_context_|.
- void Notify(SyncEngineEvent::EventCause cause);
+ // Map of all datatypes that are requesting a nudge. Can be union
+ // from multiple nudges that are coalesced. In addition, we
+ // optionally track a payload associated with each datatype (most recent
+ // payload overwrites old ones). These payloads are used by the download
+ // updates command and can contain datatype specific information the server
+ // might use.
+ syncable::ModelTypePayloadMap pending_nudge_types_;
- // Callback to change backoff state.
- void DoCanaryJob();
- void Unthrottle();
+ // null iff there is no pending nudge.
+ base::TimeTicks pending_nudge_time_;
- // Executes the pending job. Called whenever an event occurs that may
- // change conditions permitting a job to run. Like when network connection is
- // re-established, mode changes etc.
- void DoPendingJobIfPossible(bool is_canary_job);
+ // The wait interval for to the current iteration of our main loop. This is
+ // only written to by the syncer thread, and since the only reader from a
+ // different thread (NudgeSync) is called at totally random times, we don't
+ // really need to access mutually exclusively as the data races that exist
+ // are intrinsic, but do so anyway and avoid using 'volatile'.
+ WaitInterval current_wait_interval_;
+ } vault_;
- // The pointer is owned by the caller.
- browser_sync::sessions::SyncSession* CreateSyncSession(
- const browser_sync::sessions::SyncSourceInfo& info);
+ // Gets signaled whenever a thread outside of the syncer thread changes a
+ // protected field in the vault_.
+ base::ConditionVariable vault_field_changed_;
- // Creates a session for a poll and performs the sync.
- void PollTimerCallback();
+ // Used to lock everything in |vault_|.
+ base::Lock lock_;
- // Assign |start| and |end| to appropriate SyncerStep values for the
- // specified |purpose|.
- void SetSyncerStepsForPurpose(SyncSessionJob::SyncSessionJobPurpose purpose,
- SyncerStep* start,
- SyncerStep* end);
+ private:
+ // Threshold multipler for how long before user should be considered idle.
+ static const int kPollBackoffThresholdMultiplier = 10;
- // Initializes the hookup between the ServerConnectionManager and us.
- void WatchConnectionManager();
+ // SyncSession::Delegate implementation.
+ virtual void OnSilencedUntil(const base::TimeTicks& silenced_until);
+ virtual bool IsSyncingCurrentlySilenced();
+ virtual void OnReceivedShortPollIntervalUpdate(
+ const base::TimeDelta& new_interval);
+ virtual void OnReceivedLongPollIntervalUpdate(
+ const base::TimeDelta& new_interval);
+ virtual void OnShouldStopSyncingPermanently();
- // Used to update |server_connection_ok_|, see below.
- void CheckServerConnectionManagerStatus(
- HttpResponse::ServerConnectionCode code);
+ void HandleServerConnectionEvent(const ServerConnectionEvent& event);
+
+ // Collect all local state required for a sync and build a SyncSession out of
+ // it, reset state for the next time, and performs the sync cycle.
+ // See |GetAndResetNudgeSource| for details on what 'reset' means.
+ // |was_nudged| is set to true if the session returned is fulfilling a nudge.
+ // Returns once the session is finished (HasMoreToSync returns false). The
+ // caller owns the returned SyncSession.
+ sessions::SyncSession* SyncMain(Syncer* syncer,
+ bool was_throttled,
+ bool continue_sync_cycle,
+ bool* initial_sync_for_thread,
+ bool* was_nudged);
+
+ // Calculates the next sync wait time and exponential backoff state.
+ // 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. was_nudged is used
+ // in case of exponential backoff so we only allow one nudge per backoff
+ // interval.
+ WaitInterval CalculatePollingWaitTime(
+ int last_poll_wait, // in s
+ int* user_idle_milliseconds,
+ bool* continue_sync_cycle,
+ bool was_nudged);
+
+ // Helper to above function, considers effect of user idle time.
+ virtual int CalculateSyncWaitTime(int last_wait, int user_idle_ms);
+
+ // Resets the source tracking state to a clean slate and returns the current
+ // state in a SyncSourceInfo.
+ // The initial sync boolean is updated if read as a sentinel. The following
+ // two methods work in concert to achieve this goal.
+ // If |was_throttled| was true, this still discards elapsed nudges, but we
+ // treat the request as a periodic poll rather than a nudge from a source.
+ // Builds a SyncSourceInfo and returns whether a nudge occurred in the
+ // |was_nudged| parameter.
+ sessions::SyncSourceInfo GetAndResetNudgeSource(bool was_throttled,
+ bool continue_sync_cycle,
+ bool* initial_sync,
+ bool* was_nudged);
+
+ sessions::SyncSourceInfo MakeSyncSourceInfo(
+ bool nudged,
+ NudgeSource nudge_source,
+ const syncable::ModelTypePayloadMap& model_types_with_payloads,
+ bool* initial_sync);
+
+ int UserIdleTime();
+
+ void WaitUntilConnectedOrQuit();
+
+ // The thread will remain in this method until a resume is requested
+ // or shutdown is started.
+ void PauseUntilResumedOrQuit();
+
+ void EnterPausedState();
+
+ void ExitPausedState();
+
+ // For unit tests only.
+ virtual void DisableIdleDetection();
+
+ // This sets all conditions for syncer thread termination but does not
+ // actually join threads. It is expected that Stop will be called at some
+ // time after to fully stop and clean up.
+ void RequestSyncerExitAndSetThreadStopConditions();
- // Called once the first time thread_ is started to broadcast an initial
- // session snapshot containing data like initial_sync_ended. Important when
- // the client starts up and does not need to perform an initial sync.
- void SendInitialSnapshot();
+ void Notify(SyncEngineEvent::EventCause cause);
- base::Thread thread_;
+ scoped_ptr<EventListenerHookup> conn_mgr_hookup_;
// Modifiable versions of kDefaultLongPollIntervalSeconds which can be
// updated by the server.
- base::TimeDelta syncer_short_poll_interval_seconds_;
- base::TimeDelta syncer_long_poll_interval_seconds_;
-
- // Periodic timer for polling. See AdjustPolling.
- base::RepeatingTimer<SyncerThread> poll_timer_;
-
- // The mode of operation. We don't use a lock, see Start(...) comment.
- Mode mode_;
-
- // TODO(tim): Bug 26339. This needs to track more than just time I think,
- // since the nudges could be for different types. Current impl doesn't care.
- base::TimeTicks last_sync_session_end_time_;
+ 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_;
+
+ // 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,
+ NudgeSource source,
+ const syncable::ModelTypePayloadMap& model_types_with_payloads);
+
+#if defined(OS_LINUX)
+ // On Linux, we need this information in order to query idle time.
+ scoped_ptr<IdleQueryLinux> idle_query_;
+#endif
- // Have we observed a valid server connection?
- bool server_connection_ok_;
-
- // Tracks in-flight nudges so we can coalesce.
- scoped_ptr<SyncSessionJob> pending_nudge_;
-
- // Current wait state. Null if we're not in backoff and not throttled.
- scoped_ptr<WaitInterval> wait_interval_;
+ scoped_ptr<sessions::SyncSessionContext> session_context_;
- scoped_ptr<DelayProvider> delay_provider_;
+ // Set whenever the server instructs us to stop sending it requests until
+ // a specified time, and reset for each call to SyncShare. (Note that the
+ // WaitInterval::THROTTLED contract is such that we don't call SyncShare at
+ // all until the "silenced until" embargo expires.)
+ base::TimeTicks silenced_until_;
- // Invoked to run through the sync cycle.
- scoped_ptr<Syncer> syncer_;
-
- scoped_ptr<sessions::SyncSessionContext> session_context_;
+ // Useful for unit tests
+ bool disable_idle_detection_;
DISALLOW_COPY_AND_ASSIGN(SyncerThread);
};
-
} // namespace browser_sync
-// The SyncerThread manages its own internal thread and thus outlives it. We
-// don't need refcounting for posting tasks to this internal thread.
-DISABLE_RUNNABLE_METHOD_REFCOUNT(browser_sync::SyncerThread);
-
#endif // CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_H_