Commit 964cbf99 authored by Ken Rockot's avatar Ken Rockot Committed by Commit Bot

Mojo: Add some CHECKs to debug watcher crashes

Also changes an incorrect DCHECK to be a safe runtime check in the event
of racy usage by callers.

BUG=740044
TBR=jcivelli@chromium.org

Change-Id: I8725648035eda70ac5bf9fb046073f21557727bc
Reviewed-on: https://chromium-review.googlesource.com/575521Reviewed-by: default avatarKen Rockot <rockot@chromium.org>
Commit-Queue: Ken Rockot <rockot@chromium.org>
Cr-Commit-Position: refs/heads/master@{#487327}
parent 1a3d539e
...@@ -438,7 +438,8 @@ MojoResult Core::Watch(MojoHandle watcher_handle, ...@@ -438,7 +438,8 @@ MojoResult Core::Watch(MojoHandle watcher_handle,
scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handle); scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handle);
if (!dispatcher) if (!dispatcher)
return MOJO_RESULT_INVALID_ARGUMENT; return MOJO_RESULT_INVALID_ARGUMENT;
return watcher->WatchDispatcher(dispatcher, signals, condition, context); return watcher->WatchDispatcher(std::move(dispatcher), signals, condition,
context);
} }
MojoResult Core::CancelWatch(MojoHandle watcher_handle, uintptr_t context) { MojoResult Core::CancelWatch(MojoHandle watcher_handle, uintptr_t context) {
......
...@@ -25,6 +25,9 @@ bool Watch::NotifyState(const HandleSignalsState& state, ...@@ -25,6 +25,9 @@ bool Watch::NotifyState(const HandleSignalsState& state,
bool allowed_to_call_callback) { bool allowed_to_call_callback) {
AssertWatcherLockAcquired(); AssertWatcherLockAcquired();
// TODO(crbug.com/740044): Remove this CHECK.
CHECK(this);
// NOTE: This method must NEVER call into |dispatcher_| directly, because it // NOTE: This method must NEVER call into |dispatcher_| directly, because it
// may be called while |dispatcher_| holds a lock. // may be called while |dispatcher_| holds a lock.
...@@ -56,6 +59,9 @@ bool Watch::NotifyState(const HandleSignalsState& state, ...@@ -56,6 +59,9 @@ bool Watch::NotifyState(const HandleSignalsState& state,
} }
void Watch::Cancel() { void Watch::Cancel() {
// TODO(crbug.com/740044): Remove this CHECK.
CHECK(this);
RequestContext::current()->AddWatchCancelFinalizer(this); RequestContext::current()->AddWatchCancelFinalizer(this);
} }
......
...@@ -25,7 +25,7 @@ void WatcherDispatcher::NotifyHandleState(Dispatcher* dispatcher, ...@@ -25,7 +25,7 @@ void WatcherDispatcher::NotifyHandleState(Dispatcher* dispatcher,
if (it == watched_handles_.end()) if (it == watched_handles_.end())
return; return;
// Maybe fire a notification to the watch assoicated with this dispatcher, // Maybe fire a notification to the watch associated with this dispatcher,
// provided we're armed and it cares about the new state. // provided we're armed and it cares about the new state.
if (it->second->NotifyState(state, armed_)) { if (it->second->NotifyState(state, armed_)) {
ready_watches_.insert(it->second.get()); ready_watches_.insert(it->second.get());
...@@ -47,6 +47,9 @@ void WatcherDispatcher::NotifyHandleClosed(Dispatcher* dispatcher) { ...@@ -47,6 +47,9 @@ void WatcherDispatcher::NotifyHandleClosed(Dispatcher* dispatcher) {
watch = std::move(it->second); watch = std::move(it->second);
// TODO(crbug.com/740044): Remove this CHECK.
CHECK(watch);
// Wipe out all state associated with the closed dispatcher. // Wipe out all state associated with the closed dispatcher.
watches_.erase(watch->context()); watches_.erase(watch->context());
ready_watches_.erase(watch.get()); ready_watches_.erase(watch.get());
...@@ -119,6 +122,10 @@ MojoResult WatcherDispatcher::WatchDispatcher( ...@@ -119,6 +122,10 @@ MojoResult WatcherDispatcher::WatchDispatcher(
// after we've updated all our own relevant state and released |lock_|. // after we've updated all our own relevant state and released |lock_|.
{ {
base::AutoLock lock(lock_); base::AutoLock lock(lock_);
// TODO(crbug.com/740044): Remove this CHECK.
CHECK(!closed_);
if (watches_.count(context) || watched_handles_.count(dispatcher.get())) if (watches_.count(context) || watched_handles_.count(dispatcher.get()))
return MOJO_RESULT_ALREADY_EXISTS; return MOJO_RESULT_ALREADY_EXISTS;
...@@ -156,6 +163,11 @@ MojoResult WatcherDispatcher::CancelWatch(uintptr_t context) { ...@@ -156,6 +163,11 @@ MojoResult WatcherDispatcher::CancelWatch(uintptr_t context) {
watches_.erase(it); watches_.erase(it);
} }
// TODO(crbug.com/740044): Remove these CHECKs.
CHECK(watch);
CHECK(watch->dispatcher());
CHECK(this);
// Mark the watch as cancelled so no further notifications get through. // Mark the watch as cancelled so no further notifications get through.
watch->Cancel(); watch->Cancel();
...@@ -167,7 +179,12 @@ MojoResult WatcherDispatcher::CancelWatch(uintptr_t context) { ...@@ -167,7 +179,12 @@ MojoResult WatcherDispatcher::CancelWatch(uintptr_t context) {
{ {
base::AutoLock lock(lock_); base::AutoLock lock(lock_);
auto handle_it = watched_handles_.find(watch->dispatcher().get()); auto handle_it = watched_handles_.find(watch->dispatcher().get());
DCHECK(handle_it != watched_handles_.end());
// If another thread races to close this watcher handler, |watched_handles_|
// may have been cleared by the time we reach this section.
if (handle_it == watched_handles_.end())
return MOJO_RESULT_OK;
ready_watches_.erase(handle_it->second.get()); ready_watches_.erase(handle_it->second.get());
watched_handles_.erase(handle_it); watched_handles_.erase(handle_it);
} }
...@@ -229,7 +246,7 @@ MojoResult WatcherDispatcher::Arm( ...@@ -229,7 +246,7 @@ MojoResult WatcherDispatcher::Arm(
} }
WatcherDispatcher::~WatcherDispatcher() { WatcherDispatcher::~WatcherDispatcher() {
// TODO(crbug.com/74044): Remove this. // TODO(crbug.com/740044): Remove this.
CHECK(closed_); CHECK(closed_);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment