diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-25 00:46:00 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-25 00:46:00 +0000 |
commit | 63a7bb8eed936e5e9702c79e7fcac2a7a55f7017 (patch) | |
tree | 322dea709d012e37d614e7b34945a6f604bf22d0 /chrome | |
parent | d72b77dbc38d4aa0b722f706e7e1bd7910a9ddb5 (diff) | |
download | chromium_src-63a7bb8eed936e5e9702c79e7fcac2a7a55f7017.zip chromium_src-63a7bb8eed936e5e9702c79e7fcac2a7a55f7017.tar.gz chromium_src-63a7bb8eed936e5e9702c79e7fcac2a7a55f7017.tar.bz2 |
Fix a problem with the SyncChannel rewrite. DispatchReplies needs to be called after the deserializer has been popped. This now happens in the listener thread, so post a task to the IPC thread to do it.
Review URL: http://codereview.chromium.org/8175
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3971 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/common/ipc_sync_channel.cc | 76 |
1 files changed, 36 insertions, 40 deletions
diff --git a/chrome/common/ipc_sync_channel.cc b/chrome/common/ipc_sync_channel.cc index 01ac78e..1f60def 100644 --- a/chrome/common/ipc_sync_channel.cc +++ b/chrome/common/ipc_sync_channel.cc @@ -126,14 +126,6 @@ class SyncChannel::ReceivedSyncMsgQueue : } } - // Called on the IPC thread when the current sync Send() call is unblocked. - void DidUnblock() { - if (!received_replies_.empty()) { - MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( - this, &ReceivedSyncMsgQueue::DispatchReplies)); - } - } - // SyncChannel calls this in its destructor. void RemoveListener(Channel::Listener* listener) { AutoLock auto_lock(message_lock_); @@ -167,14 +159,6 @@ class SyncChannel::ReceivedSyncMsgQueue : static base::LazyInstance<base::ThreadLocalPointer<ReceivedSyncMsgQueue> > lazy_tls_ptr_; - private: - ReceivedSyncMsgQueue() : - dispatch_event_(CreateEvent(NULL, TRUE, FALSE, NULL)), - task_pending_(false), - listener_message_loop_(MessageLoop::current()), - listener_count_(0) { - } - // Called on the ipc thread to check if we can unblock any current Send() // calls based on a queued reply. void DispatchReplies() { @@ -188,6 +172,14 @@ class SyncChannel::ReceivedSyncMsgQueue : } } + private: + ReceivedSyncMsgQueue() : + dispatch_event_(CreateEvent(NULL, TRUE, FALSE, NULL)), + task_pending_(false), + listener_message_loop_(MessageLoop::current()), + listener_count_(0) { + } + // Holds information about a queued synchronous message. struct ReceivedMessage { ReceivedMessage(Message* m, Channel::Listener* l, const std::wstring& i) @@ -252,12 +244,25 @@ void SyncChannel::SyncContext::Push(SyncMessage* sync_msg) { } bool SyncChannel::SyncContext::Pop() { - AutoLock auto_lock(deserializers_lock_); - PendingSyncMsg msg = deserializers_.back(); - delete msg.deserializer; - CloseHandle(msg.done_event); - deserializers_.pop_back(); - return msg.send_result; + bool result; + { + AutoLock auto_lock(deserializers_lock_); + PendingSyncMsg msg = deserializers_.back(); + delete msg.deserializer; + CloseHandle(msg.done_event); + deserializers_.pop_back(); + result = msg.send_result; + } + + // We got a reply to a synchronous Send() call that's blocking the listener + // thread. However, further down the call stack there could be another + // blocking Send() call, whose reply we received after we made this last + // Send() call. So check if we have any queued replies available that + // can now unblock the listener thread. + ipc_message_loop()->PostTask(FROM_HERE, NewRunnableMethod( + received_sync_msgs_.get(), &ReceivedSyncMsgQueue::DispatchReplies)); + + return result; } HANDLE SyncChannel::SyncContext::GetSendDoneEvent() { @@ -274,26 +279,17 @@ void SyncChannel::SyncContext::DispatchMessages() { } bool SyncChannel::SyncContext::TryToUnblockListener(const Message* msg) { - { - AutoLock auto_lock(deserializers_lock_); - if (deserializers_.empty() || - !SyncMessage::IsMessageReplyTo(*msg, deserializers_.back().id)) { - return false; - } - - if (!msg->is_reply_error()) { - deserializers_.back().send_result = deserializers_.back().deserializer-> - SerializeOutputParameters(*msg); - } - SetEvent(deserializers_.back().done_event); + AutoLock auto_lock(deserializers_lock_); + if (deserializers_.empty() || + !SyncMessage::IsMessageReplyTo(*msg, deserializers_.back().id)) { + return false; } - // We got a reply to a synchronous Send() call that's blocking the listener - // thread. However, further down the call stack there could be another - // blocking Send() call, whose reply we received after we made this last - // Send() call. So check if we have any queued replies available that - // can now unblock the listener thread. - received_sync_msgs_->DidUnblock(); + if (!msg->is_reply_error()) { + deserializers_.back().send_result = deserializers_.back().deserializer-> + SerializeOutputParameters(*msg); + } + SetEvent(deserializers_.back().done_event); return true; } |