diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-12 00:38:26 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-12 00:38:26 +0000 |
commit | 4df10d61191c966dae69b34040018929980a8e42 (patch) | |
tree | 2528911e17dade2a656cbe584faeac9fa5470924 /chrome/common/ipc_sync_channel.cc | |
parent | 45654210820836150b76cb594454fbbc2a0eb144 (diff) | |
download | chromium_src-4df10d61191c966dae69b34040018929980a8e42.zip chromium_src-4df10d61191c966dae69b34040018929980a8e42.tar.gz chromium_src-4df10d61191c966dae69b34040018929980a8e42.tar.bz2 |
Fix a race condition in SyncChannel that would happen if a nested Send occurred in between the time that SetEvent was called on the current Send's done_event and when OnObjectSignalled was called. The pending signal would be cancelled and since the event was already reset, when we watched it again later OnObjectSignalled would never be called. The fix is to make it a manual reset event.
BUG=1474092
Review URL: http://codereview.chromium.org/10817
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@5238 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/common/ipc_sync_channel.cc')
-rw-r--r-- | chrome/common/ipc_sync_channel.cc | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/chrome/common/ipc_sync_channel.cc b/chrome/common/ipc_sync_channel.cc index 0861790..68402b8 100644 --- a/chrome/common/ipc_sync_channel.cc +++ b/chrome/common/ipc_sync_channel.cc @@ -175,6 +175,8 @@ class SyncChannel::ReceivedSyncMsgQueue : } private: + // See the comment in SyncChannel::SyncChannel for why this event is created + // as manual reset. ReceivedSyncMsgQueue() : dispatch_event_(CreateEvent(NULL, TRUE, FALSE, NULL)), task_pending_(false), @@ -238,9 +240,13 @@ SyncChannel::SyncContext::~SyncContext() { // we know how to deserialize the reply. Returns a handle that's set when // the reply has arrived. void SyncChannel::SyncContext::Push(SyncMessage* sync_msg) { + // The event is created as manual reset because in between SetEvent and + // OnObjectSignalled, another Send can happen which would stop the watcher + // from being called. The event would get watched later, when the nested + // Send completes, so the event will need to remain set. PendingSyncMsg pending(SyncMessage::GetMessageId(*sync_msg), sync_msg->GetReplyDeserializer(), - CreateEvent(NULL, FALSE, FALSE, NULL)); + CreateEvent(NULL, TRUE, FALSE, NULL)); AutoLock auto_lock(deserializers_lock_); deserializers_.push_back(pending); } |