| Index: mojo/common/handle_watcher.cc
|
| diff --git a/mojo/common/handle_watcher.cc b/mojo/common/handle_watcher.cc
|
| index 84e8b64fb9ad7a93fd0fb5ca1b211178a5f3bb6b..71d4eb03857c0dee5a97a7562c305301a5aed540 100644
|
| --- a/mojo/common/handle_watcher.cc
|
| +++ b/mojo/common/handle_watcher.cc
|
| @@ -14,6 +14,7 @@
|
| #include "base/message_loop/message_loop.h"
|
| #include "base/message_loop/message_loop_proxy.h"
|
| #include "base/synchronization/lock.h"
|
| +#include "base/synchronization/waitable_event.h"
|
| #include "base/threading/thread.h"
|
| #include "base/time/time.h"
|
| #include "mojo/common/message_pump_mojo.h"
|
| @@ -68,7 +69,10 @@ class WatcherBackend : public MessagePumpMojoHandler {
|
| virtual ~WatcherBackend();
|
|
|
| void StartWatching(const WatchData& data);
|
| - void StopWatching(WatcherID watcher_id);
|
| +
|
| + // Cancels a previously schedule request to start a watch. When done signals
|
| + // |event|.
|
| + void StopWatching(WatcherID watcher_id, base::WaitableEvent* event);
|
|
|
| private:
|
| typedef std::map<Handle, WatchData> HandleToWatchDataMap;
|
| @@ -107,15 +111,16 @@ void WatcherBackend::StartWatching(const WatchData& data) {
|
| data.deadline);
|
| }
|
|
|
| -void WatcherBackend::StopWatching(WatcherID watcher_id) {
|
| +void WatcherBackend::StopWatching(WatcherID watcher_id,
|
| + base::WaitableEvent* event) {
|
| // Because of the thread hop it is entirely possible to get here and not
|
| // have a valid handle registered for |watcher_id|.
|
| Handle handle;
|
| - if (!GetMojoHandleByWatcherID(watcher_id, &handle))
|
| - return;
|
| -
|
| - handle_to_data_.erase(handle);
|
| - message_pump_mojo->RemoveHandler(handle);
|
| + if (GetMojoHandleByWatcherID(watcher_id, &handle)) {
|
| + handle_to_data_.erase(handle);
|
| + message_pump_mojo->RemoveHandler(handle);
|
| + }
|
| + event->Signal();
|
| }
|
|
|
| void WatcherBackend::RemoveAndNotify(const Handle& handle,
|
| @@ -208,7 +213,7 @@ WatcherID WatcherThreadManager::StartWatching(
|
| data.message_loop = base::MessageLoopProxy::current();
|
| DCHECK_NE(static_cast<base::MessageLoopProxy*>(NULL),
|
| data.message_loop.get());
|
| - // We outlive |thread_|, so it's safe to use Unretained() here.
|
| + // We own |thread_|, so it's safe to use Unretained() here.
|
| thread_.message_loop()->PostTask(
|
| FROM_HERE,
|
| base::Bind(&WatcherBackend::StartWatching,
|
| @@ -218,12 +223,17 @@ WatcherID WatcherThreadManager::StartWatching(
|
| }
|
|
|
| void WatcherThreadManager::StopWatching(WatcherID watcher_id) {
|
| - // We outlive |thread_|, so it's safe to use Unretained() here.
|
| + // We own |thread_|, so it's safe to use Unretained() here.
|
| + base::WaitableEvent event(true, false);
|
| thread_.message_loop()->PostTask(
|
| FROM_HERE,
|
| base::Bind(&WatcherBackend::StopWatching,
|
| base::Unretained(&backend_),
|
| - watcher_id));
|
| + watcher_id,
|
| + &event));
|
| +
|
| + // We need to block until the handle is actually removed.
|
| + event.Wait();
|
| }
|
|
|
| WatcherThreadManager::WatcherThreadManager()
|
|
|