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() |