Chromium Code Reviews| Index: ipc/ipc_sync_channel.cc |
| diff --git a/ipc/ipc_sync_channel.cc b/ipc/ipc_sync_channel.cc |
| index f3c538421386a3fc03c076501e4b7d7eb10be632..fe4531c874b015a5622fbae3b2242b0434312eb6 100644 |
| --- a/ipc/ipc_sync_channel.cc |
| +++ b/ipc/ipc_sync_channel.cc |
| @@ -64,6 +64,7 @@ class SyncChannel::ReceivedSyncMsgQueue : |
| // We set the event in case the listener thread is blocked (or is about |
| // to). In case it's not, the PostTask dispatches the messages. |
| message_queue_.push_back(QueuedMessage(new Message(msg), context)); |
| + message_queue_modified_ = true; |
| } |
| dispatch_event_.Signal(); |
| @@ -89,27 +90,33 @@ class SyncChannel::ReceivedSyncMsgQueue : |
| } |
| void DispatchMessages(SyncContext* dispatching_context) { |
| - SyncMessageQueue delayed_queue; |
| + bool first_time = true; |
| + SyncMessageQueue::iterator it; |
| while (true) { |
| - Message* message; |
| + Message* message = NULL; |
| scoped_refptr<SyncChannel::SyncContext> context; |
| { |
| base::AutoLock auto_lock(message_lock_); |
| - if (message_queue_.empty()) { |
| - message_queue_ = delayed_queue; |
| - break; |
| + if (first_time || message_queue_modified_) { |
| + it = message_queue_.begin(); |
| + first_time = false; |
| + message_queue_modified_ = false; |
|
piman
2012/01/10 04:33:17
In case of nested dispatches, I'm not sure we can
Josh Horwich
2012/01/10 20:30:25
Done.
But in a different manner - now I maintain
|
| + } |
| + for (; it != message_queue_.end(); it++) { |
| + if (!it->context->restrict_dispatch() || |
| + it->context == dispatching_context) { |
| + message = it->message; |
| + context = it->context; |
| + it = message_queue_.erase(it); |
| + break; |
| + } |
| } |
| - |
| - message = message_queue_.front().message; |
| - context = message_queue_.front().context; |
| - message_queue_.pop_front(); |
| - } |
| - if (context->restrict_dispatch() && context != dispatching_context) { |
| - delayed_queue.push_back(QueuedMessage(message, context)); |
| - } else { |
| - context->OnDispatchMessage(*message); |
| - delete message; |
| } |
| + |
| + if (message == NULL) |
| + break; |
| + context->OnDispatchMessage(*message); |
| + delete message; |
| } |
| } |
| @@ -122,6 +129,7 @@ class SyncChannel::ReceivedSyncMsgQueue : |
| if (iter->context == context) { |
| delete iter->message; |
| iter = message_queue_.erase(iter); |
| + message_queue_modified_ = true; |
| } else { |
| iter++; |
| } |
| @@ -169,6 +177,7 @@ class SyncChannel::ReceivedSyncMsgQueue : |
| // See the comment in SyncChannel::SyncChannel for why this event is created |
| // as manual reset. |
| ReceivedSyncMsgQueue() : |
| + message_queue_modified_(false), |
| dispatch_event_(true, false), |
| listener_message_loop_(base::MessageLoopProxy::current()), |
| task_pending_(false), |
| @@ -185,8 +194,9 @@ class SyncChannel::ReceivedSyncMsgQueue : |
| scoped_refptr<SyncChannel::SyncContext> context; |
| }; |
| - typedef std::deque<QueuedMessage> SyncMessageQueue; |
| + typedef std::list<QueuedMessage> SyncMessageQueue; |
| SyncMessageQueue message_queue_; |
| + bool message_queue_modified_; // Used to signal DispatchMessages to rescan |
| std::vector<QueuedMessage> received_replies_; |