Chromium Code Reviews| 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..592b1ee00dd76e0b7bc106361857ff4397631e1d 100644 |
| --- a/components/sync/driver/glue/ui_model_worker.cc |
| +++ b/components/sync/driver/glue/ui_model_worker.cc |
| @@ -9,7 +9,6 @@ |
| #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 { |
| @@ -19,6 +18,11 @@ namespace { |
| void CallDoWorkAndSignalEvent(const WorkCallback& work, |
| syncer::ScopedEventSignal scoped_event_signal, |
| SyncerError* error_info) { |
| + if (scoped_event_signal.IsSignaled()) { |
| + *error_info = CANNOT_DO_WORK; |
| + return; |
| + } |
| + |
| *error_info = work.Run(); |
| // The event in |scoped_event_signal| is signaled at the end of this scope. |
| } |
| @@ -27,7 +31,10 @@ void CallDoWorkAndSignalEvent(const WorkCallback& work, |
| 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) { |
| +} |
| SyncerError UIModelWorker::DoWorkAndWaitUntilDoneImpl( |
| const WorkCallback& work) { |
| @@ -38,26 +45,29 @@ SyncerError UIModelWorker::DoWorkAndWaitUntilDoneImpl( |
| return work.Run(); |
| } |
| - // 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); |
| + // RequestStop hasn't been called so reset the signal to do more work. |
| + work_done_or_abandoned_.Reset(); |
|
fdoray
2016/11/14 14:24:34
This can happen:
THREAD ACTION
Sync: DoWorkAndW
maxbogue
2016/11/14 20:53:21
This actually occurred to me on Friday right befor
|
| if (!ui_thread_->PostTask(FROM_HERE, |
| base::Bind(&CallDoWorkAndSignalEvent, work, |
| base::Passed(syncer::ScopedEventSignal( |
| - &work_done_or_abandoned)), |
| + &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(); |
| + work_done_or_abandoned_.Wait(); |
| return error_info; |
| } |
| +void UIModelWorker::RequestStop() { |
| + DCHECK(ui_thread_->BelongsToCurrentThread()); |
| + ModelSafeWorker::RequestStop(); |
| + work_done_or_abandoned_.Signal(); |
| +} |
| + |
| ModelSafeGroup UIModelWorker::GetModelSafeGroup() { |
| return GROUP_UI; |
| } |