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

Unified Diff: components/sync/driver/glue/ui_model_worker.cc

Issue 2505913003: [Sync] Signal UIModelWorker to abort on sync shutdown. (Closed)
Patch Set: self-review Created 4 years, 1 month 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 side-by-side diff with in-line comments
Download patch
Index: components/sync/driver/glue/ui_model_worker.cc
diff --git a/components/sync/driver/glue/ui_model_worker.cc b/components/sync/driver/glue/ui_model_worker.cc
index c812f9a9b54ed6b95cf0c974a3d07f778f2eac48..25cfeb48e05ab5b0ec376c94e900d5d981c3aba2 100644
--- a/components/sync/driver/glue/ui_model_worker.cc
+++ b/components/sync/driver/glue/ui_model_worker.cc
@@ -9,55 +9,90 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
-#include "base/synchronization/waitable_event.h"
#include "components/sync/base/scoped_event_signal.h"
namespace syncer {
namespace {
-void CallDoWorkAndSignalEvent(const WorkCallback& work,
- syncer::ScopedEventSignal scoped_event_signal,
- SyncerError* error_info) {
- *error_info = work.Run();
- // The event in |scoped_event_signal| is signaled at the end of this scope.
+class ScopedEventSignalWithUIModelWorker {
maxbogue 2016/11/18 18:26:51 nit: ScopedEventSignalWithWorker would be plenty d
fdoray 2016/11/21 16:57:55 Done.
+ public:
+ ScopedEventSignalWithUIModelWorker(
+ scoped_refptr<UIModelWorker> ui_model_worker,
+ base::WaitableEvent* event)
+ : ui_model_worker_(std::move(ui_model_worker)),
+ scoped_event_signal_(event) {}
+
+ ScopedEventSignalWithUIModelWorker(ScopedEventSignalWithUIModelWorker&&) =
+ default;
+ ScopedEventSignalWithUIModelWorker& operator=(
+ ScopedEventSignalWithUIModelWorker&&) = default;
+
+ bool IsStopped() const { return ui_model_worker_->IsStopped(); }
+
+ private:
+ // This reference prevents the event in |scoped_event_signal_| from being
+ // signaled after being deleted.
+ scoped_refptr<UIModelWorker> ui_model_worker_;
+
+ ScopedEventSignal scoped_event_signal_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedEventSignalWithUIModelWorker);
+};
+
+void CallDoWorkAndSignalEvent(
+ const WorkCallback& work,
+ ScopedEventSignalWithUIModelWorker scoped_event_signal_with_ui_model_worker,
maxbogue 2016/11/18 18:26:51 nit: scoped_event_signal_with_worker
fdoray 2016/11/21 16:57:55 Done.
+ SyncerError* error_info) {
+ if (!scoped_event_signal_with_ui_model_worker.IsStopped())
+ *error_info = work.Run();
+ // The event in |scoped_event_signal_with_ui_model_worker| is signaled at the
+ // end of this scope.
}
} // namespace
UIModelWorker::UIModelWorker(
scoped_refptr<base::SingleThreadTaskRunner> ui_thread)
- : ui_thread_(std::move(ui_thread)) {}
+ : ui_thread_(std::move(ui_thread)),
+ work_done_or_abandoned_(base::WaitableEvent::ResetPolicy::MANUAL,
+ base::WaitableEvent::InitialState::NOT_SIGNALED),
+ stop_requested_(base::WaitableEvent::ResetPolicy::MANUAL,
+ base::WaitableEvent::InitialState::NOT_SIGNALED) {
+ sequence_checker_.DetachFromSequence();
+}
SyncerError UIModelWorker::DoWorkAndWaitUntilDoneImpl(
const WorkCallback& work) {
- SyncerError error_info;
- if (ui_thread_->BelongsToCurrentThread()) {
- DLOG(WARNING) << "DoWorkAndWaitUntilDone called from "
- << "ui_loop_. Probably a nested invocation?";
- return work.Run();
- }
+ DCHECK(sequence_checker_.CalledOnValidSequence());
+ DCHECK(!ui_thread_->BelongsToCurrentThread());
- // Signaled when the task is deleted, i.e. after it runs or when it is
- // abandoned.
- base::WaitableEvent work_done_or_abandoned(
- base::WaitableEvent::ResetPolicy::AUTOMATIC,
- base::WaitableEvent::InitialState::NOT_SIGNALED);
-
- if (!ui_thread_->PostTask(FROM_HERE,
- base::Bind(&CallDoWorkAndSignalEvent, work,
- base::Passed(syncer::ScopedEventSignal(
- &work_done_or_abandoned)),
- &error_info))) {
+ SyncerError error_info;
+ work_done_or_abandoned_.Reset();
+
+ if (!ui_thread_->PostTask(
+ FROM_HERE,
+ base::Bind(&CallDoWorkAndSignalEvent, work,
+ base::Passed(syncer::ScopedEventSignalWithUIModelWorker(
+ this, &work_done_or_abandoned_)),
+ &error_info))) {
DLOG(WARNING) << "Could not post work to UI loop.";
error_info = CANNOT_DO_WORK;
return error_info;
}
- work_done_or_abandoned.Wait();
+
+ base::WaitableEvent* events[] = {&work_done_or_abandoned_, &stop_requested_};
+ base::WaitableEvent::WaitMany(events, arraysize(events));
return error_info;
}
+void UIModelWorker::RequestStop() {
+ DCHECK(ui_thread_->BelongsToCurrentThread());
+ ModelSafeWorker::RequestStop();
+ stop_requested_.Signal();
+}
+
ModelSafeGroup UIModelWorker::GetModelSafeGroup() {
return GROUP_UI;
}

Powered by Google App Engine
This is Rietveld 408576698