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

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

Issue 235010: Reverting 27117. (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
(Empty)
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
3 // found in the LICENSE file.
4 //
5 // *THIS EXISTS FOR EXPERIMENTATION AND TESTING WHILE WE REPLACE PTHREADS
6 // WITH CHROME THREADS IN SYNC CODE*
7
8 // A class to run the syncer on a thread. Uses PIMPL to wrap the old, original
9 // pthreads implementation of SyncerThread.
10 #ifndef CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_PTHREADS_H_
11 #define CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_PTHREADS_H_
12
13 #include <list>
14 #include <map>
15 #include <queue>
16 #include <vector>
17
18 #include "base/basictypes.h"
19 #include "base/scoped_ptr.h"
20 #include "chrome/browser/sync/engine/all_status.h"
21 #include "chrome/browser/sync/engine/client_command_channel.h"
22 #include "chrome/browser/sync/util/event_sys-inl.h"
23 #include "chrome/browser/sync/util/pthread_helpers.h"
24 #include "chrome/browser/sync/engine/syncer_thread.h"
25 #include "testing/gtest/include/gtest/gtest_prod.h" // For FRIEND_TEST
26
27 class EventListenerHookup;
28
29 namespace syncable {
30 class DirectoryManager;
31 struct DirectoryManagerEvent;
32 }
33
34 namespace browser_sync {
35
36 class ModelSafeWorker;
37 class ServerConnectionManager;
38 class Syncer;
39 class TalkMediator;
40 class URLFactory;
41 struct ServerConnectionEvent;
42 struct SyncerEvent;
43 struct SyncerShutdownEvent;
44 struct TalkMediatorEvent;
45
46 // The legacy implementation of SyncerThread using pthreads, kept around for
47 // historical experimentation until a new version is finalized.
48 class SyncerThreadPthreadImpl {
49 public:
50 virtual ~SyncerThreadPthreadImpl();
51
52 virtual void WatchConnectionManager(ServerConnectionManager* conn_mgr);
53 // Creates and starts a syncer thread.
54 // Returns true if it creates a thread or if there's currently a thread
55 // running and false otherwise.
56 virtual bool Start();
57
58 // Stop processing. A max wait of at least 2*server RTT time is recommended.
59 // returns true if we stopped, false otherwise.
60 virtual bool Stop(int max_wait);
61
62 // Nudges the syncer to sync with a delay specified. This API is for access
63 // from the SyncerThread's controller and will cause a mutex lock.
64 virtual bool NudgeSyncer(int milliseconds_from_now,
65 SyncerThread::NudgeSource source);
66
67 // Registers this thread to watch talk mediator events.
68 virtual void WatchTalkMediator(TalkMediator* talk_mediator);
69
70 virtual void WatchClientCommands(ClientCommandChannel* channel);
71
72 virtual SyncerEventChannel* channel();
73
74 private:
75 friend class SyncerThreadPthreads;
76 SyncerThreadPthreadImpl(ClientCommandChannel* command_channel,
77 syncable::DirectoryManager* mgr,
78 ServerConnectionManager* connection_manager, AllStatus* all_status,
79 ModelSafeWorker* model_safe_worker);
80
81 // A few members to gate the rate at which we nudge the syncer.
82 enum {
83 kNudgeRateLimitCount = 6,
84 kNudgeRateLimitTime = 180,
85 };
86
87 // A queue of all scheduled nudges. One insertion for every call to
88 // NudgeQueue().
89 typedef std::pair<timespec, SyncerThread::NudgeSource> NudgeObject;
90
91 struct IsTimeSpecGreater {
92 inline bool operator() (const NudgeObject& lhs, const NudgeObject& rhs) {
93 return lhs.first.tv_sec == rhs.first.tv_sec ?
94 lhs.first.tv_nsec > rhs.first.tv_nsec :
95 lhs.first.tv_sec > rhs.first.tv_sec;
96 }
97 };
98
99 typedef std::priority_queue<NudgeObject, std::vector<NudgeObject>,
100 IsTimeSpecGreater> NudgeQueue;
101
102 // Threshold multipler for how long before user should be considered idle.
103 static const int kPollBackoffThresholdMultiplier = 10;
104
105 friend void* RunSyncerThread(void* syncer_thread);
106 void* Run();
107 void HandleDirectoryManagerEvent(
108 const syncable::DirectoryManagerEvent& event);
109 void HandleSyncerEvent(const SyncerEvent& event);
110 void HandleClientCommand(ClientCommandChannel::EventType event);
111
112 void HandleServerConnectionEvent(const ServerConnectionEvent& event);
113
114 void HandleTalkMediatorEvent(const TalkMediatorEvent& event);
115
116 void* ThreadMain();
117 void ThreadMainLoop();
118
119 void SyncMain(Syncer* syncer);
120
121 // Calculates the next sync wait time in seconds. last_poll_wait is the time
122 // duration of the previous polling timeout which was used.
123 // user_idle_milliseconds is updated by this method, and is a report of the
124 // full amount of time since the last period of activity for the user. The
125 // continue_sync_cycle parameter is used to determine whether or not we are
126 // calculating a polling wait time that is a continuation of an sync cycle
127 // which terminated while the syncer still had work to do.
128 int CalculatePollingWaitTime(
129 const AllStatus::Status& status,
130 int last_poll_wait, // in s
131 int* user_idle_milliseconds,
132 bool* continue_sync_cycle);
133 // Helper to above function, considers effect of user idle time.
134 int CalculateSyncWaitTime(int last_wait, int user_idle_ms);
135
136 // Sets the source value of the controlled syncer's updates_source value.
137 // The initial sync boolean is updated if read as a sentinel. The following
138 // two methods work in concert to achieve this goal.
139 void UpdateNudgeSource(const timespec& now, bool* continue_sync_cycle,
140 bool* initial_sync);
141 void SetUpdatesSource(bool nudged, SyncerThread::NudgeSource nudge_source,
142 bool* initial_sync);
143
144 // For unit tests only.
145 void DisableIdleDetection() { disable_idle_detection_ = true; }
146
147 // False when we want to stop the thread.
148 bool stop_syncer_thread_;
149
150 // We use one mutex for all members except the channel.
151 PThreadMutex mutex_;
152 typedef PThreadScopedLock<PThreadMutex> MutexLock;
153
154 // Handle of the running thread.
155 pthread_t thread_;
156 bool thread_running_;
157
158 // Gets signaled whenever a thread outside of the syncer thread changes a
159 // member variable.
160 PThreadCondVar changed_;
161
162 // State of the server connection.
163 bool connected_;
164
165 // State of the notification framework is tracked by these values.
166 bool p2p_authenticated_;
167 bool p2p_subscribed_;
168
169 scoped_ptr<EventListenerHookup> client_command_hookup_;
170 scoped_ptr<EventListenerHookup> conn_mgr_hookup_;
171 const AllStatus* allstatus_;
172
173 Syncer* syncer_;
174
175 syncable::DirectoryManager* dirman_;
176 ServerConnectionManager* scm_;
177
178 // Modifiable versions of kDefaultLongPollIntervalSeconds which can be
179 // updated by the server.
180 int syncer_short_poll_interval_seconds_;
181 int syncer_long_poll_interval_seconds_;
182
183 // The time we wait between polls in seconds. This is used as lower bound on
184 // our wait time. Updated once per loop from the command line flag.
185 int syncer_polling_interval_;
186
187 // The upper bound on the nominal wait between polls in seconds. Note that
188 // this bounds the "nominal" poll interval, while the the actual interval
189 // also takes previous failures into account.
190 int syncer_max_interval_;
191
192 scoped_ptr<SyncerEventChannel> syncer_event_channel_;
193
194 // This causes syncer to start syncing ASAP. If the rate of requests is too
195 // high the request will be silently dropped. mutex_ should be held when
196 // this is called.
197 void NudgeSyncImpl(int milliseconds_from_now,
198 SyncerThread::NudgeSource source);
199
200 NudgeQueue nudge_queue_;
201
202 scoped_ptr<EventListenerHookup> talk_mediator_hookup_;
203 ClientCommandChannel* const command_channel_;
204 scoped_ptr<EventListenerHookup> directory_manager_hookup_;
205 scoped_ptr<EventListenerHookup> syncer_events_;
206
207 // Handles any tasks that will result in model changes (modifications of
208 // syncable::Entries). Pass this to the syncer created and managed by |this|.
209 // Only non-null in syncapi case.
210 scoped_ptr<ModelSafeWorker> model_safe_worker_;
211
212 // Useful for unit tests
213 bool disable_idle_detection_;
214
215 DISALLOW_COPY_AND_ASSIGN(SyncerThreadPthreadImpl);
216 };
217
218 // A new-version SyncerThread pimpl wrapper for the old legacy implementation.
219 class SyncerThreadPthreads : public SyncerThread {
220 FRIEND_TEST(SyncerThreadTest, CalculateSyncWaitTime);
221 FRIEND_TEST(SyncerThreadTest, CalculatePollingWaitTime);
222 FRIEND_TEST(SyncerThreadWithSyncerTest, Polling);
223 FRIEND_TEST(SyncerThreadWithSyncerTest, Nudge);
224 friend class SyncerThreadWithSyncerTest;
225 friend class SyncerThreadFactory;
226 public:
227 virtual ~SyncerThreadPthreads() {}
228
229 virtual void WatchConnectionManager(ServerConnectionManager* conn_mgr) {
230 impl_->WatchConnectionManager(conn_mgr);
231 }
232 virtual bool Start() {
233 return impl_->Start();
234 }
235 virtual bool Stop(int max_wait) {
236 return impl_->Stop(max_wait);
237 }
238 virtual bool NudgeSyncer(int milliseconds_from_now, NudgeSource source) {
239 return impl_->NudgeSyncer(milliseconds_from_now, source);
240 }
241 virtual void WatchTalkMediator(TalkMediator* talk_mediator) {
242 impl_->WatchTalkMediator(talk_mediator);
243 }
244 virtual void WatchClientCommands(ClientCommandChannel* channel) {
245 impl_->WatchClientCommands(channel);
246 }
247 virtual SyncerEventChannel* channel() {
248 return impl_->channel();
249 }
250 protected:
251 SyncerThreadPthreads(ClientCommandChannel* command_channel,
252 syncable::DirectoryManager* mgr,
253 ServerConnectionManager* connection_manager, AllStatus* all_status,
254 ModelSafeWorker* model_safe_worker);
255 virtual void SetConnected(bool connected) {
256 impl_->connected_ = connected;
257 }
258 virtual void SetSyncerPollingInterval(int interval) {
259 impl_->syncer_polling_interval_ = interval;
260 }
261 virtual void SetSyncerShortPollInterval(base::TimeDelta interval) {
262 impl_->syncer_short_poll_interval_seconds_ = static_cast<int>(
263 interval.InSeconds());
264 }
265 virtual void DisableIdleDetection() { impl_->disable_idle_detection_ = true; }
266 virtual int CalculateSyncWaitTime(int last_wait, int user_idle_ms) {
267 return impl_->CalculateSyncWaitTime(last_wait, user_idle_ms);
268 }
269 virtual int CalculatePollingWaitTime(
270 const AllStatus::Status& status,
271 int last_poll_wait, // in s
272 int* user_idle_milliseconds,
273 bool* continue_sync_cycle) {
274 return impl_->CalculatePollingWaitTime(status, last_poll_wait,
275 user_idle_milliseconds, continue_sync_cycle);
276 }
277 private:
278 scoped_ptr<SyncerThreadPthreadImpl> impl_;
279 DISALLOW_COPY_AND_ASSIGN(SyncerThreadPthreads);
280 };
281
282 } // namespace browser_sync
283
284 #endif // CHROME_BROWSER_SYNC_ENGINE_SYNCER_THREAD_PTHREADS_H_
OLDNEW
« no previous file with comments | « chrome/browser/sync/engine/syncapi.cc ('k') | chrome/browser/sync/engine/syncer_thread_pthreads.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698