diff options
author | dumi@chromium.org <dumi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-02 20:21:12 +0000 |
---|---|---|
committer | dumi@chromium.org <dumi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-02 20:21:12 +0000 |
commit | fc2c2d216c090e18aa62d0fc19af2753ccd2dee9 (patch) | |
tree | 1bea5471880aa317c50c11541e99243ac3f114b5 | |
parent | a442180f04ae8958e36e8f2b6f068d1e4db6a3bc (diff) | |
download | chromium_src-fc2c2d216c090e18aa62d0fc19af2753ccd2dee9.zip chromium_src-fc2c2d216c090e18aa62d0fc19af2753ccd2dee9.tar.gz chromium_src-fc2c2d216c090e18aa62d0fc19af2753ccd2dee9.tar.bz2 |
Making sure that we do not destroy a WaitableEvent while another
thread might still be inside its Signal() method.
TEST=none
BUG=32023
Review URL: http://codereview.chromium.org/661382
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@40413 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/common/db_message_filter.h | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/chrome/common/db_message_filter.h b/chrome/common/db_message_filter.h index f2612fb..41967a0 100644 --- a/chrome/common/db_message_filter.h +++ b/chrome/common/db_message_filter.h @@ -46,7 +46,7 @@ class DBMessageFilter : public IPC::ChannelProxy::MessageFilter { ResultType SendAndWait(IPC::Message* message, int message_id, ResultType default_result) { - ResultType result; + ResultType result = default_result; base::WaitableEvent waitable_event(false, false); DBMessageState state = { reinterpret_cast<intptr_t>(&result), &waitable_event }; @@ -58,13 +58,15 @@ class DBMessageFilter : public IPC::ChannelProxy::MessageFilter { Send(message); base::WaitableEvent* events[2] = { shutdown_event_, &waitable_event }; - if (base::WaitableEvent::WaitMany(events, 2)) { - return result; - } else { - AutoLock msgs_awaiting_replies_autolock(messages_awaiting_replies_lock_); - messages_awaiting_replies_->Remove(message_id); - return default_result; - } + base::WaitableEvent::WaitMany(events, 2); + + // Locking on messages_awaiting_replies_ guarantees that either the IO + // thread won't enter OnResponse(), or if it's already in OnResponse(), + // then WaitableEvent::Signal() will get a chance to do all its work + // before waitable_event is deleted. + AutoLock msgs_awaiting_replies_autolock(messages_awaiting_replies_lock_); + messages_awaiting_replies_->Remove(message_id); + return result; } // Processes incoming message |message| from the browser process. @@ -97,7 +99,6 @@ class DBMessageFilter : public IPC::ChannelProxy::MessageFilter { AutoLock msgs_awaiting_replies_autolock(messages_awaiting_replies_lock_); DBMessageState *state = messages_awaiting_replies_->Lookup(message_id); if (state) { - messages_awaiting_replies_->Remove(message_id); *reinterpret_cast<ResultType*>(state->result_address_) = result; state->waitable_event_->Signal(); } |