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

Side by Side Diff: components/history/core/browser/history_model_worker.h

Issue 2757193003: [Sync] Do not deadlock when joining sync thread with a pending HistoryModelWorker task. (Closed)
Patch Set: self-review Created 3 years, 9 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
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 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 #ifndef COMPONENTS_HISTORY_CORE_BROWSER_HISTORY_MODEL_WORKER_H_ 5 #ifndef COMPONENTS_HISTORY_CORE_BROWSER_HISTORY_MODEL_WORKER_H_
6 #define COMPONENTS_HISTORY_CORE_BROWSER_HISTORY_MODEL_WORKER_H_ 6 #define COMPONENTS_HISTORY_CORE_BROWSER_HISTORY_MODEL_WORKER_H_
7 7
8 #include <memory> 8 #include <memory>
9 9
10 #include "base/macros.h" 10 #include "base/macros.h"
11 #include "base/memory/ref_counted.h" 11 #include "base/memory/ref_counted.h"
12 #include "base/memory/weak_ptr.h" 12 #include "base/memory/weak_ptr.h"
13 #include "base/single_thread_task_runner.h" 13 #include "base/single_thread_task_runner.h"
14 #include "base/synchronization/lock.h"
15 #include "base/synchronization/waitable_event.h"
14 #include "base/task/cancelable_task_tracker.h" 16 #include "base/task/cancelable_task_tracker.h"
15 #include "components/sync/engine/model_safe_worker.h" 17 #include "components/sync/engine/model_safe_worker.h"
16 18
17 namespace history { 19 namespace history {
18 class HistoryService; 20 class HistoryService;
19 } 21 }
20 22
21 namespace browser_sync { 23 namespace browser_sync {
22 24
23 // A syncer::ModelSafeWorker for history models that accepts requests 25 // A syncer::ModelSafeWorker for history models that accepts requests
24 // from the syncapi that need to be fulfilled on the history thread. 26 // from the syncapi that need to be fulfilled on the history thread.
25 class HistoryModelWorker : public syncer::ModelSafeWorker { 27 class HistoryModelWorker : public syncer::ModelSafeWorker {
26 public: 28 public:
27 explicit HistoryModelWorker( 29 explicit HistoryModelWorker(
28 const base::WeakPtr<history::HistoryService>& history_service, 30 const base::WeakPtr<history::HistoryService>& history_service,
29 const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread); 31 const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread);
30 32
31 // syncer::ModelSafeWorker implementation. 33 // syncer::ModelSafeWorker implementation.
34 void RequestStop() override;
32 syncer::ModelSafeGroup GetModelSafeGroup() override; 35 syncer::ModelSafeGroup GetModelSafeGroup() override;
33 bool IsOnModelThread() override; 36 bool IsOnModelThread() override;
34 37
35 protected: 38 protected:
36 syncer::SyncerError DoWorkAndWaitUntilDoneImpl( 39 syncer::SyncerError DoWorkAndWaitUntilDoneImpl(
37 const syncer::WorkCallback& work) override; 40 const syncer::WorkCallback& work) override;
38 41
39 private: 42 private:
43 class WorkerTask;
44
40 ~HistoryModelWorker() override; 45 ~HistoryModelWorker() override;
41 46
47 // Called before a WorkCallback starts running. If this returns false, the
maxbogue 2017/03/20 16:52:37 nit: mention the side effect of this function some
fdoray 2017/03/20 18:54:54 n/a
48 // WorkCallback must not run.
49 bool WillRunWorkCallback();
50
51 // Called after a WorkCallback has run.
52 void DidRunWorkCallback();
53
42 const base::WeakPtr<history::HistoryService> history_service_; 54 const base::WeakPtr<history::HistoryService> history_service_;
43 55
44 // A reference to the UI thread's task runner. 56 // A reference to the UI thread's task runner.
45 const scoped_refptr<base::SingleThreadTaskRunner> ui_thread_; 57 const scoped_refptr<base::SingleThreadTaskRunner> ui_thread_;
46 58
59 // Signaled when a task posted by DoWorkAndWaitUntilDoneImpl() is deleted,
60 // i.e. after it runs or when it is abandoned. Reset at the beginning of every
61 // DoWorkAndWaitUntilDoneImpl() call.
62 base::WaitableEvent work_done_or_abandoned_;
63
64 // Signaled to unblock DoWorkAndWaitUntilDoneImpl() and prevent any
65 // WorkCallback from being scheduled when RequestStop() is called and there is
66 // no pending task from this worker on the history DB thread.
67 base::WaitableEvent stop_requested_;
68
69 // True if a WorkCallback posted by this worker is currently running.
70 bool work_callback_running_ = false;
71
72 // Synchronizes access to |stop_requested_| and |work_callback_running_|.
73 base::Lock lock_;
74
47 // Helper object to make sure we don't leave tasks running on the history 75 // Helper object to make sure we don't leave tasks running on the history
48 // thread. 76 // thread.
49 std::unique_ptr<base::CancelableTaskTracker> cancelable_tracker_; 77 std::unique_ptr<base::CancelableTaskTracker> cancelable_tracker_;
50 78
79 // Verifies that calls to DoWorkAndWaitUntilDoneImpl() are sequenced.
80 base::SequenceChecker sequence_checker_;
81
51 DISALLOW_COPY_AND_ASSIGN(HistoryModelWorker); 82 DISALLOW_COPY_AND_ASSIGN(HistoryModelWorker);
52 }; 83 };
53 84
54 } // namespace browser_sync 85 } // namespace browser_sync
55 86
56 #endif // COMPONENTS_HISTORY_CORE_BROWSER_HISTORY_MODEL_WORKER_H_ 87 #endif // COMPONENTS_HISTORY_CORE_BROWSER_HISTORY_MODEL_WORKER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698