Index: chrome/browser/sync/glue/browser_thread_model_worker.cc |
diff --git a/chrome/browser/sync/glue/browser_thread_model_worker.cc b/chrome/browser/sync/glue/browser_thread_model_worker.cc |
index f92b6885f7e905cf6aef42f359bbfbea901c1b54..3d8cfa1d8aa55e40079ed33f5e99ec190635e482 100644 |
--- a/chrome/browser/sync/glue/browser_thread_model_worker.cc |
+++ b/chrome/browser/sync/glue/browser_thread_model_worker.cc |
@@ -14,28 +14,31 @@ using content::BrowserThread; |
namespace browser_sync { |
BrowserThreadModelWorker::BrowserThreadModelWorker( |
- BrowserThread::ID thread, syncer::ModelSafeGroup group) |
- : thread_(thread), group_(group) { |
+ BrowserThread::ID thread, syncer::ModelSafeGroup group, |
+ syncer::WorkerLoopDestructionObserver* observer) |
+ : ModelSafeWorker(observer), |
+ thread_(thread), group_(group) { |
} |
-syncer::SyncerError BrowserThreadModelWorker::DoWorkAndWaitUntilDone( |
+syncer::SyncerError BrowserThreadModelWorker::DoWorkAndWaitUntilDoneImpl( |
const syncer::WorkCallback& work) { |
syncer::SyncerError error = syncer::UNSET; |
if (BrowserThread::CurrentlyOn(thread_)) { |
DLOG(WARNING) << "Already on thread " << thread_; |
return work.Run(); |
} |
- WaitableEvent done(false, false); |
+ |
if (!BrowserThread::PostTask( |
thread_, |
FROM_HERE, |
- base::Bind(&BrowserThreadModelWorker::CallDoWorkAndSignalTask, this, |
- work, &done, &error))) { |
+ base::Bind(&BrowserThreadModelWorker::CallDoWorkAndSignalTask, |
+ this, work, |
+ work_done_or_stopped(), &error))) { |
DLOG(WARNING) << "Failed to post task to thread " << thread_; |
error = syncer::CANNOT_DO_WORK; |
return error; |
} |
- done.Wait(); |
+ work_done_or_stopped()->Wait(); |
return error; |
} |
@@ -45,17 +48,29 @@ syncer::ModelSafeGroup BrowserThreadModelWorker::GetModelSafeGroup() { |
BrowserThreadModelWorker::~BrowserThreadModelWorker() {} |
+void BrowserThreadModelWorker::RegisterForLoopDestruction() { |
+ if (BrowserThread::CurrentlyOn(thread_)) { |
+ MessageLoop::current()->AddDestructionObserver(this); |
+ } else { |
+ BrowserThread::PostTask( |
+ thread_, FROM_HERE, |
+ Bind(&BrowserThreadModelWorker::RegisterForLoopDestruction, this)); |
+ } |
+} |
+ |
void BrowserThreadModelWorker::CallDoWorkAndSignalTask( |
const syncer::WorkCallback& work, |
WaitableEvent* done, |
syncer::SyncerError* error) { |
DCHECK(BrowserThread::CurrentlyOn(thread_)); |
- *error = work.Run(); |
+ if (!IsStopped()) |
+ *error = work.Run(); |
done->Signal(); |
} |
-DatabaseModelWorker::DatabaseModelWorker() |
- : BrowserThreadModelWorker(BrowserThread::DB, syncer::GROUP_DB) { |
+DatabaseModelWorker::DatabaseModelWorker( |
+ syncer::WorkerLoopDestructionObserver* observer) |
+ : BrowserThreadModelWorker(BrowserThread::DB, syncer::GROUP_DB, observer) { |
} |
void DatabaseModelWorker::CallDoWorkAndSignalTask( |
@@ -67,8 +82,10 @@ void DatabaseModelWorker::CallDoWorkAndSignalTask( |
DatabaseModelWorker::~DatabaseModelWorker() {} |
-FileModelWorker::FileModelWorker() |
- : BrowserThreadModelWorker(BrowserThread::FILE, syncer::GROUP_FILE) { |
+FileModelWorker::FileModelWorker( |
+ syncer::WorkerLoopDestructionObserver* observer) |
+ : BrowserThreadModelWorker(BrowserThread::FILE, syncer::GROUP_FILE, |
+ observer) { |
} |
void FileModelWorker::CallDoWorkAndSignalTask( |