diff options
Diffstat (limited to 'chrome/browser/sync/engine/syncer_thread.h')
-rw-r--r-- | chrome/browser/sync/engine/syncer_thread.h | 575 |
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_ |