Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Side by Side Diff: chrome/browser/sync/engine/syncer_thread_timed_stop.h

Issue 214033: Use chrome/base synchronization primitives and threads instead of... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // 4 //
5 // A class to run the syncer on a thread. 5 // A class to run the syncer on a thread. This guy is the closest chrome-based
6 6 // (as opposed to pthreads based) SyncerThread to the old pthread implementation
7 #ifndef CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_H_ 7 // in semantics, as it supports a timeout on Stop() -- It is just an override of
8 #define CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_H_ 8 // two methods from SyncerThread: ThreadMain and Stop -- to provide this.
9 #ifndef CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_TIMED_STOP_H_
10 #define CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_TIMED_STOP_H_
9 11
10 #include <list> 12 #include <list>
11 #include <map> 13 #include <map>
12 #include <queue> 14 #include <queue>
13 #include <vector> 15 #include <vector>
14 16
15 #include "base/basictypes.h" 17 #include "chrome/browser/sync/engine/syncer_thread.h"
16 #include "base/scoped_ptr.h"
17 #include "chrome/browser/sync/engine/all_status.h"
18 #include "chrome/browser/sync/engine/client_command_channel.h"
19 #include "chrome/browser/sync/util/event_sys-inl.h"
20 #include "chrome/browser/sync/util/pthread_helpers.h"
21 #include "testing/gtest/include/gtest/gtest_prod.h" // For FRIEND_TEST
22
23 class EventListenerHookup;
24
25 namespace syncable {
26 class DirectoryManager;
27 struct DirectoryManagerEvent;
28 }
29 18
30 namespace browser_sync { 19 namespace browser_sync {
31 20
32 class ModelSafeWorker; 21 class SyncerThreadTimedStop : public SyncerThread {
33 class ServerConnectionManager;
34 class Syncer;
35 class TalkMediator;
36 class URLFactory;
37 struct ServerConnectionEvent;
38 struct SyncerEvent;
39 struct SyncerShutdownEvent;
40 struct TalkMediatorEvent;
41
42 class SyncerThread {
43 FRIEND_TEST(SyncerThreadTest, CalculateSyncWaitTime); 22 FRIEND_TEST(SyncerThreadTest, CalculateSyncWaitTime);
44 FRIEND_TEST(SyncerThreadTest, CalculatePollingWaitTime); 23 FRIEND_TEST(SyncerThreadTest, CalculatePollingWaitTime);
24 FRIEND_TEST(SyncerThreadWithSyncerTest, Polling);
25 FRIEND_TEST(SyncerThreadWithSyncerTest, Nudge);
26 friend class SyncerThreadWithSyncerTest;
27 friend class SyncerThreadFactory;
28 public:
29 virtual ~SyncerThreadTimedStop() {}
45 30
46 public: 31 // Stop processing. This version comes with a supported max_wait.
47 friend class SyncerThreadTest; 32 // A max wait of at least 2*server RTT time is recommended.
33 // Returns true if we stopped, false otherwise.
34 virtual bool Stop(int max_wait);
48 35
49 enum NudgeSource { 36 private:
50 kUnknown = 0, 37 SyncerThreadTimedStop(ClientCommandChannel* command_channel,
51 kNotification,
52 kLocal,
53 kContinuation
54 };
55
56 // Server can overwrite these values via client commands.
57 // Standard short poll. This is used when XMPP is off.
58 static const int kDefaultShortPollIntervalSeconds = 60;
59 // Long poll is used when XMPP is on.
60 static const int kDefaultLongPollIntervalSeconds = 3600;
61 // 30 minutes by default. If exponential backoff kicks in, this is the
62 // longest possible poll interval.
63 static const int kDefaultMaxPollIntervalMs = 30 * 60 * 1000;
64
65 SyncerThread(ClientCommandChannel* command_channel,
66 syncable::DirectoryManager* mgr, 38 syncable::DirectoryManager* mgr,
67 ServerConnectionManager* connection_manager, AllStatus* all_status, 39 ServerConnectionManager* connection_manager, AllStatus* all_status,
68 ModelSafeWorker* model_safe_worker); 40 ModelSafeWorker* model_safe_worker);
69 ~SyncerThread(); 41 virtual void ThreadMain();
70 42
71 void WatchConnectionManager(ServerConnectionManager* conn_mgr); 43 // We use this to track when our synthesized thread loop is active, so we can
72 // Creates and starts a syncer thread. 44 // timed-wait for it to become false. For this and only this (temporary)
73 // Returns true if it creates a thread or if there's currently a thread 45 // implementation, we protect this variable using our parent lock_.
74 // running and false otherwise. 46 bool in_thread_main_loop_;
75 bool Start();
76 47
77 // Stop processing. A max wait of at least 2*server RTT time is recommended. 48 DISALLOW_COPY_AND_ASSIGN(SyncerThreadTimedStop);
78 // returns true if we stopped, false otherwise.
79 bool Stop(int max_wait);
80
81 // Nudges the syncer to sync with a delay specified. This API is for access
82 // from the SyncerThread's controller and will cause a mutex lock.
83 bool NudgeSyncer(int milliseconds_from_now, NudgeSource source);
84
85 // Registers this thread to watch talk mediator events.
86 void WatchTalkMediator(TalkMediator* talk_mediator);
87
88 void WatchClientCommands(ClientCommandChannel* channel);
89
90 SyncerEventChannel* channel();
91
92 private:
93 // A few members to gate the rate at which we nudge the syncer.
94 enum {
95 kNudgeRateLimitCount = 6,
96 kNudgeRateLimitTime = 180,
97 };
98
99 // A queue of all scheduled nudges. One insertion for every call to
100 // NudgeQueue().
101 typedef std::pair<timespec, NudgeSource> NudgeObject;
102
103 struct IsTimeSpecGreater {
104 inline bool operator() (const NudgeObject& lhs, const NudgeObject& rhs) {
105 return lhs.first.tv_sec == rhs.first.tv_sec ?
106 lhs.first.tv_nsec > rhs.first.tv_nsec :
107 lhs.first.tv_sec > rhs.first.tv_sec;
108 }
109 };
110
111 typedef std::priority_queue<NudgeObject, std::vector<NudgeObject>,
112 IsTimeSpecGreater> NudgeQueue;
113
114 // Threshold multipler for how long before user should be considered idle.
115 static const int kPollBackoffThresholdMultiplier = 10;
116
117 friend void* RunSyncerThread(void* syncer_thread);
118 void* Run();
119 void HandleDirectoryManagerEvent(
120 const syncable::DirectoryManagerEvent& event);
121 void HandleSyncerEvent(const SyncerEvent& event);
122 void HandleClientCommand(ClientCommandChannel::EventType event);
123
124 void HandleServerConnectionEvent(const ServerConnectionEvent& event);
125
126 void HandleTalkMediatorEvent(const TalkMediatorEvent& event);
127
128 void* ThreadMain();
129 void ThreadMainLoop();
130
131 void SyncMain(Syncer* syncer);
132
133 // Calculates the next sync wait time in seconds. last_poll_wait is the time
134 // duration of the previous polling timeout which was used.
135 // user_idle_milliseconds is updated by this method, and is a report of the
136 // full amount of time since the last period of activity for the user. The
137 // continue_sync_cycle parameter is used to determine whether or not we are
138 // calculating a polling wait time that is a continuation of an sync cycle
139 // which terminated while the syncer still had work to do.
140 int CalculatePollingWaitTime(
141 const AllStatus::Status& status,
142 int last_poll_wait, // in s
143 int* user_idle_milliseconds,
144 bool* continue_sync_cycle);
145 // Helper to above function, considers effect of user idle time.
146 int CalculateSyncWaitTime(int last_wait, int user_idle_ms);
147
148 // Sets the source value of the controlled syncer's updates_source value.
149 // The initial sync boolean is updated if read as a sentinel. The following
150 // two methods work in concert to achieve this goal.
151 void UpdateNudgeSource(const timespec& now, bool* continue_sync_cycle,
152 bool* initial_sync);
153 void SetUpdatesSource(bool nudged, NudgeSource nudge_source,
154 bool* initial_sync);
155
156 // For unit tests only.
157 void DisableIdleDetection() { disable_idle_detection_ = true; }
158
159 // False when we want to stop the thread.
160 bool stop_syncer_thread_;
161
162 // We use one mutex for all members except the channel.
163 PThreadMutex mutex_;
164 typedef PThreadScopedLock<PThreadMutex> MutexLock;
165
166 // Handle of the running thread.
167 pthread_t thread_;
168 bool thread_running_;
169
170 // Gets signaled whenever a thread outside of the syncer thread changes a
171 // member variable.
172 PThreadCondVar changed_;
173
174 // State of the server connection.
175 bool connected_;
176
177 // State of the notification framework is tracked by these values.
178 bool p2p_authenticated_;
179 bool p2p_subscribed_;
180
181 scoped_ptr<EventListenerHookup> client_command_hookup_;
182 scoped_ptr<EventListenerHookup> conn_mgr_hookup_;
183 const AllStatus* allstatus_;
184
185 Syncer* syncer_;
186
187 syncable::DirectoryManager* dirman_;
188 ServerConnectionManager* scm_;
189
190 // Modifiable versions of kDefaultLongPollIntervalSeconds which can be
191 // updated by the server.
192 int syncer_short_poll_interval_seconds_;
193 int syncer_long_poll_interval_seconds_;
194
195 // The time we wait between polls in seconds. This is used as lower bound on
196 // our wait time. Updated once per loop from the command line flag.
197 int syncer_polling_interval_;
198
199 // The upper bound on the nominal wait between polls in seconds. Note that
200 // this bounds the "nominal" poll interval, while the the actual interval
201 // also takes previous failures into account.
202 int syncer_max_interval_;
203
204 scoped_ptr<SyncerEventChannel> syncer_event_channel_;
205
206 // This causes syncer to start syncing ASAP. If the rate of requests is too
207 // high the request will be silently dropped. mutex_ should be held when
208 // this is called.
209 void NudgeSyncImpl(int milliseconds_from_now, NudgeSource source);
210
211 NudgeQueue nudge_queue_;
212
213 scoped_ptr<EventListenerHookup> talk_mediator_hookup_;
214 ClientCommandChannel* const command_channel_;
215 scoped_ptr<EventListenerHookup> directory_manager_hookup_;
216 scoped_ptr<EventListenerHookup> syncer_events_;
217
218 // Handles any tasks that will result in model changes (modifications of
219 // syncable::Entries). Pass this to the syncer created and managed by |this|.
220 // Only non-null in syncapi case.
221 scoped_ptr<ModelSafeWorker> model_safe_worker_;
222
223 // Useful for unit tests
224 bool disable_idle_detection_;
225
226 DISALLOW_COPY_AND_ASSIGN(SyncerThread);
227 }; 49 };
228 50
229 } // namespace browser_sync 51 } // namespace browser_sync
230 52
231 #endif // CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_H_ 53 #endif // CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_TIMED_STOP_H_
OLDNEW
« no previous file with comments | « chrome/browser/sync/engine/syncer_thread_pthreads.cc ('k') | chrome/browser/sync/engine/syncer_thread_timed_stop.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698