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

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 {
20 class HistoryDBTask;
18 class HistoryService; 21 class HistoryService;
19 } 22 }
20 23
21 namespace browser_sync { 24 namespace browser_sync {
22 25
23 // A syncer::ModelSafeWorker for history models that accepts requests 26 // A syncer::ModelSafeWorker for history models that accepts requests
24 // from the syncapi that need to be fulfilled on the history thread. 27 // from the syncapi that need to be fulfilled on the history thread.
25 class HistoryModelWorker : public syncer::ModelSafeWorker { 28 class HistoryModelWorker : public syncer::ModelSafeWorker {
26 public: 29 public:
27 explicit HistoryModelWorker( 30 explicit HistoryModelWorker(
28 const base::WeakPtr<history::HistoryService>& history_service, 31 const base::WeakPtr<history::HistoryService>& history_service,
29 const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread); 32 const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread);
30 33
31 // syncer::ModelSafeWorker implementation. 34 // syncer::ModelSafeWorker implementation.
35 void RequestStop() override;
32 syncer::ModelSafeGroup GetModelSafeGroup() override; 36 syncer::ModelSafeGroup GetModelSafeGroup() override;
33 bool IsOnModelThread() override; 37 bool IsOnModelThread() override;
34 38
35 protected: 39 protected:
36 syncer::SyncerError DoWorkAndWaitUntilDoneImpl( 40 syncer::SyncerError DoWorkAndWaitUntilDoneImpl(
37 const syncer::WorkCallback& work) override; 41 const syncer::WorkCallback& work) override;
38 42
39 private: 43 private:
44 class WorkerTask;
maxbogue 2017/03/20 19:55:50 Is this still necessary?
fdoray 2017/03/21 17:21:31 No. Removed it.
45
40 ~HistoryModelWorker() override; 46 ~HistoryModelWorker() override;
41 47
48 void ScheduleHistoryDBTaskFromUIThread(
49 std::unique_ptr<history::HistoryDBTask> worker_task,
50 syncer::SyncerError* error);
51
42 const base::WeakPtr<history::HistoryService> history_service_; 52 const base::WeakPtr<history::HistoryService> history_service_;
43 53
44 // A reference to the UI thread's task runner. 54 // A reference to the UI thread's task runner.
45 const scoped_refptr<base::SingleThreadTaskRunner> ui_thread_; 55 const scoped_refptr<base::SingleThreadTaskRunner> ui_thread_;
46 56
57 // Signaled when a WorkCallback posted by DoWorkAndWaitUntilDoneImpl()
58 // finishes to run or is abandoned. Reset at the beginning of
59 // DoWorkAndWaitUntilDoneImpl().
60 base::WaitableEvent work_done_or_abandoned_;
61
62 // True if DoWorkAndWaitUntilDoneImpl() is blocked on a UI task.
63 bool ui_task_pending_ = false;
64
65 // Synchronizes calls to ModelSafeWorker::RequestStop()/IsStopped() and
66 // work_done_or_abandoned_.Reset() and all accesses to |ui_task_pending_|.
maxbogue 2017/03/20 19:55:50 I think this is really just for ui_task_pending_..
fdoray 2017/03/21 17:21:31 Added comment about potential deadlock at the top
67 base::Lock lock_;
68
47 // Helper object to make sure we don't leave tasks running on the history 69 // Helper object to make sure we don't leave tasks running on the history
48 // thread. 70 // thread.
49 std::unique_ptr<base::CancelableTaskTracker> cancelable_tracker_; 71 std::unique_ptr<base::CancelableTaskTracker> cancelable_tracker_;
50 72
73 // Verifies that calls to DoWorkAndWaitUntilDoneImpl() are sequenced.
74 base::SequenceChecker sequence_checker_;
75
51 DISALLOW_COPY_AND_ASSIGN(HistoryModelWorker); 76 DISALLOW_COPY_AND_ASSIGN(HistoryModelWorker);
52 }; 77 };
53 78
54 } // namespace browser_sync 79 } // namespace browser_sync
55 80
56 #endif // COMPONENTS_HISTORY_CORE_BROWSER_HISTORY_MODEL_WORKER_H_ 81 #endif // COMPONENTS_HISTORY_CORE_BROWSER_HISTORY_MODEL_WORKER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698