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

Side by Side Diff: chrome/browser/sync/glue/bookmark_model_worker.h

Issue 553015: Support for multiple sync ModelSafeWorkers.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 11 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) 2006-2008 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 #ifndef CHROME_BROWSER_SYNC_GLUE_BOOKMARK_MODEL_WORKER_H_
6 #define CHROME_BROWSER_SYNC_GLUE_BOOKMARK_MODEL_WORKER_H_
7
8 #include "base/condition_variable.h"
9 #include "base/lock.h"
10 #include "base/task.h"
11 #include "base/waitable_event.h"
12 #include "chrome/browser/sync/engine/syncapi.h"
13
14 class MessageLoop;
15
16 namespace browser_sync {
17
18 // A ModelSafeWorker for bookmarks that accepts work requests from the syncapi
19 // that need to be fulfilled from the MessageLoop home to the BookmarkModel
20 // (this is typically the "main" UI thread).
21 //
22 // Lifetime note: Instances of this class will generally be owned by the
23 // SyncerThread. When the SyncerThread _object_ is destroyed, the
24 // BookmarkModelWorker will be destroyed. The SyncerThread object is destroyed
25 // after the actual syncer pthread has exited.
26 class BookmarkModelWorker
27 : public sync_api::ModelSafeWorkerInterface {
28 public:
29 explicit BookmarkModelWorker(MessageLoop* bookmark_model_loop)
30 : state_(WORKING),
31 pending_work_(NULL),
32 syncapi_has_shutdown_(false),
33 bookmark_model_loop_(bookmark_model_loop),
34 syncapi_event_(&lock_) {
35 }
36 virtual ~BookmarkModelWorker();
37
38 // A simple task to signal a waitable event after calling DoWork on a visitor.
39 class CallDoWorkAndSignalTask : public Task {
40 public:
41 CallDoWorkAndSignalTask(ModelSafeWorkerInterface::Visitor* visitor,
42 base::WaitableEvent* work_done,
43 BookmarkModelWorker* scheduler)
44 : visitor_(visitor), work_done_(work_done), scheduler_(scheduler) {
45 }
46 virtual ~CallDoWorkAndSignalTask() { }
47
48 // Task implementation.
49 virtual void Run();
50
51 private:
52 // Task data - a visitor that knows how to DoWork, and a waitable event
53 // to signal after the work has been done.
54 ModelSafeWorkerInterface::Visitor* visitor_;
55 base::WaitableEvent* work_done_;
56
57 // The BookmarkModelWorker responsible for scheduling us.
58 BookmarkModelWorker* const scheduler_;
59
60 DISALLOW_COPY_AND_ASSIGN(CallDoWorkAndSignalTask);
61 };
62
63 // Called by the UI thread on shutdown of the sync service. Blocks until
64 // the BookmarkModelWorker has safely met termination conditions, namely that
65 // no task scheduled by CallDoWorkFromModelSafeThreadAndWait remains un-
66 // processed and that syncapi will not schedule any further work for us to do.
67 void Stop();
68
69 // ModelSafeWorkerInterface implementation. Called on syncapi SyncerThread.
70 virtual void CallDoWorkFromModelSafeThreadAndWait(
71 ModelSafeWorkerInterface::Visitor* visitor);
72
73 // Upon receiving this idempotent call, the ModelSafeWorkerInterface can
74 // assume no work will ever be scheduled again from now on. If it has any work
75 // that it has not yet completed, it must make sure to run it as soon as
76 // possible as the Syncer is trying to shut down. Called from the CoreThread.
77 void OnSyncerShutdownComplete();
78
79 // Callback from |pending_work_| to notify us that it has been run.
80 // Called on |bookmark_model_loop_|.
81 void OnTaskCompleted() { pending_work_ = NULL; }
82
83 private:
84 // The life-cycle of a BookmarkModelWorker in three states.
85 enum State {
86 // We hit the ground running in this state and remain until
87 // the UI loop calls Stop().
88 WORKING,
89 // Stop() sequence has been initiated, but we have not received word that
90 // the SyncerThread has terminated and doesn't need us anymore. Since the
91 // UI MessageLoop is not running at this point, we manually process any
92 // last pending_task_ that the Syncer throws at us, effectively dedicating
93 // the UI thread to terminating the Syncer.
94 RUNNING_MANUAL_SHUTDOWN_PUMP,
95 // We have come to a complete stop, no scheduled work remains, and no work
96 // will be scheduled from now until our destruction.
97 STOPPED,
98 };
99
100 // This is set by the UI thread, but is not explicitly thread safe, so only
101 // read this value from other threads when you know it is absolutely safe (e.g
102 // there is _no_ way we can be in CallDoWork with state_ = STOPPED, so it is
103 // safe to read / compare in this case).
104 State state_;
105
106 // We keep a reference to any task we have scheduled so we can gracefully
107 // force them to run if the syncer is trying to shutdown.
108 Task* pending_work_;
109
110 // Set by the SyncCoreThread when Syncapi shutdown has completed and the
111 // SyncerThread has terminated, so no more work will be scheduled. Read by
112 // the UI thread in Stop().
113 bool syncapi_has_shutdown_;
114
115 // The BookmarkModel's home-sweet-home MessageLoop.
116 MessageLoop* const bookmark_model_loop_;
117
118 // We use a Lock for all data members and a ConditionVariable to synchronize.
119 // We do this instead of using a WaitableEvent and a bool condition in order
120 // to guard against races that could arise due to the fact that the lack of a
121 // barrier permits instructions to be reordered by compiler optimizations.
122 // Possible or not, that route makes for very fragile code due to existence
123 // of theoretical races.
124 Lock lock_;
125
126 // Used as a barrier at shutdown to ensure the SyncerThread terminates before
127 // we allow the UI thread to return from Stop(). This gets signalled whenever
128 // one of two events occur: a new pending_work_ task was scheduled, or the
129 // SyncerThread has terminated. We only care about (1) when we are in Stop(),
130 // because we have to manually Run() the task.
131 ConditionVariable syncapi_event_;
132
133 DISALLOW_COPY_AND_ASSIGN(BookmarkModelWorker);
134 };
135
136 } // namespace browser_sync
137
138 #endif // CHROME_BROWSER_SYNC_GLUE_BOOKMARK_MODEL_WORKER_H_
OLDNEW
« no previous file with comments | « chrome/browser/sync/engine/verify_updates_command.cc ('k') | chrome/browser/sync/glue/bookmark_model_worker.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698