Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10533)

Unified Diff: chrome/common/ipc_sync_channel.cc

Issue 16554: WaitableEvent (Closed)
Patch Set: Addresssing darin's comments (round 2) Created 11 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/common/ipc_sync_channel.h ('k') | chrome/common/ipc_sync_message.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/common/ipc_sync_channel.cc
diff --git a/chrome/common/ipc_sync_channel.cc b/chrome/common/ipc_sync_channel.cc
index 45e42d6bbc9663dc5912ede78eaac79e8604569b..4f1e71f9d99cc33f4a7e59fc8023dec19d0ff0b0 100644
--- a/chrome/common/ipc_sync_channel.cc
+++ b/chrome/common/ipc_sync_channel.cc
@@ -2,19 +2,24 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <windows.h>
-
#include "chrome/common/ipc_sync_channel.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/thread_local.h"
-#include "chrome/common/child_process.h"
+#include "base/message_loop.h"
+#include "base/waitable_event.h"
+#include "base/waitable_event_watcher.h"
#include "chrome/common/ipc_logging.h"
#include "chrome/common/ipc_sync_message.h"
+#if !defined(OS_WIN)
+#define INFINITE -1
+#endif
+
using base::TimeDelta;
using base::TimeTicks;
+using base::WaitableEvent;
namespace IPC {
// When we're blocked in a Send(), we need to process incoming synchronous
@@ -34,8 +39,6 @@ namespace IPC {
// SyncChannel objects on the same thread (since one object can receive a
// sync message while another one is blocked).
-class SyncChannel::ReceivedSyncMsgQueue;
-
class SyncChannel::ReceivedSyncMsgQueue :
public base::RefCountedThreadSafe<ReceivedSyncMsgQueue> {
public:
@@ -70,7 +73,7 @@ class SyncChannel::ReceivedSyncMsgQueue :
message_queue_.push_back(QueuedMessage(new Message(msg), context));
}
- SetEvent(dispatch_event_);
+ dispatch_event_.Signal();
if (!was_task_pending) {
listener_message_loop_->PostTask(FROM_HERE, NewRunnableMethod(
this, &ReceivedSyncMsgQueue::DispatchMessagesTask));
@@ -143,7 +146,7 @@ class SyncChannel::ReceivedSyncMsgQueue :
}
}
- HANDLE dispatch_event() { return dispatch_event_; }
+ WaitableEvent* dispatch_event() { return &dispatch_event_; }
MessageLoop* listener_message_loop() { return listener_message_loop_; }
// Holds a pointer to the per-thread ReceivedSyncMsgQueue object.
@@ -167,9 +170,9 @@ class SyncChannel::ReceivedSyncMsgQueue :
// 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),
+ dispatch_event_(true, false),
listener_message_loop_(MessageLoop::current()),
+ task_pending_(false),
listener_count_(0) {
}
@@ -181,14 +184,14 @@ class SyncChannel::ReceivedSyncMsgQueue :
};
typedef std::deque<QueuedMessage> SyncMessageQueue;
- SyncMessageQueue message_queue_;
+ SyncMessageQueue message_queue_;
std::vector<QueuedMessage> received_replies_;
// Set when we got a synchronous message that we must respond to as the
// sender needs its reply before it can reply to our original synchronous
// message.
- ScopedHandle dispatch_event_;
+ WaitableEvent dispatch_event_;
MessageLoop* listener_message_loop_;
Lock message_lock_;
bool task_pending_;
@@ -202,10 +205,10 @@ SyncChannel::SyncContext::SyncContext(
Channel::Listener* listener,
MessageFilter* filter,
MessageLoop* ipc_thread,
- HANDLE shutdown_event)
+ WaitableEvent* shutdown_event)
: ChannelProxy::Context(listener, filter, ipc_thread),
- shutdown_event_(shutdown_event),
- received_sync_msgs_(ReceivedSyncMsgQueue::AddContext()){
+ received_sync_msgs_(ReceivedSyncMsgQueue::AddContext()),
+ shutdown_event_(shutdown_event) {
}
SyncChannel::SyncContext::~SyncContext() {
@@ -217,13 +220,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
+ // The event is created as manual reset because in between Signal 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, TRUE, FALSE, NULL));
+ new WaitableEvent(true, false));
AutoLock auto_lock(deserializers_lock_);
deserializers_.push_back(pending);
}
@@ -234,7 +237,8 @@ bool SyncChannel::SyncContext::Pop() {
AutoLock auto_lock(deserializers_lock_);
PendingSyncMsg msg = deserializers_.back();
delete msg.deserializer;
- CloseHandle(msg.done_event);
+ delete msg.done_event;
+ msg.done_event = NULL;
deserializers_.pop_back();
result = msg.send_result;
}
@@ -250,12 +254,12 @@ bool SyncChannel::SyncContext::Pop() {
return result;
}
-HANDLE SyncChannel::SyncContext::GetSendDoneEvent() {
+WaitableEvent* SyncChannel::SyncContext::GetSendDoneEvent() {
AutoLock auto_lock(deserializers_lock_);
return deserializers_.back().done_event;
}
-HANDLE SyncChannel::SyncContext::GetDispatchEvent() {
+WaitableEvent* SyncChannel::SyncContext::GetDispatchEvent() {
return received_sync_msgs_->dispatch_event();
}
@@ -274,7 +278,7 @@ bool SyncChannel::SyncContext::TryToUnblockListener(const Message* msg) {
deserializers_.back().send_result = deserializers_.back().deserializer->
SerializeOutputParameters(*msg);
}
- SetEvent(deserializers_.back().done_event);
+ deserializers_.back().done_event->Signal();
return true;
}
@@ -327,7 +331,7 @@ void SyncChannel::SyncContext::OnSendTimeout(int message_id) {
PendingSyncMessageQueue::iterator iter;
for (iter = deserializers_.begin(); iter != deserializers_.end(); iter++) {
if (iter->id == message_id) {
- SetEvent(iter->done_event);
+ iter->done_event->Signal();
break;
}
}
@@ -337,11 +341,11 @@ void SyncChannel::SyncContext::CancelPendingSends() {
AutoLock auto_lock(deserializers_lock_);
PendingSyncMessageQueue::iterator iter;
for (iter = deserializers_.begin(); iter != deserializers_.end(); iter++)
- SetEvent(iter->done_event);
+ iter->done_event->Signal();
}
-void SyncChannel::SyncContext::OnObjectSignaled(HANDLE object) {
- DCHECK(object == shutdown_event_);
+void SyncChannel::SyncContext::OnWaitableEventSignaled(WaitableEvent* event) {
+ DCHECK(event == shutdown_event_);
// Process shut down before we can get a reply to a synchronous message.
// Cancel pending Send calls, which will end up setting the send done event.
CancelPendingSends();
@@ -351,7 +355,8 @@ void SyncChannel::SyncContext::OnObjectSignaled(HANDLE object) {
SyncChannel::SyncChannel(
const std::wstring& channel_id, Channel::Mode mode,
Channel::Listener* listener, MessageFilter* filter,
- MessageLoop* ipc_message_loop, bool create_pipe_now, HANDLE shutdown_event)
+ MessageLoop* ipc_message_loop, bool create_pipe_now,
+ WaitableEvent* shutdown_event)
: ChannelProxy(
channel_id, mode, ipc_message_loop,
new SyncContext(listener, filter, ipc_message_loop, shutdown_event),
@@ -362,7 +367,7 @@ SyncChannel::SyncChannel(
// message loop running under it or not, so we wouldn't know whether to
// stop or keep watching. So we always watch it, and create the event as
// manual reset since the object watcher might otherwise reset the event
- // when we're doing a WaitForMultipleObjects.
+ // when we're doing a WaitMany.
dispatch_watcher_.StartWatching(sync_context()->GetDispatchEvent(), this);
}
@@ -381,7 +386,7 @@ bool SyncChannel::SendWithTimeout(Message* message, int timeout_ms) {
// *this* might get deleted in WaitForReply.
scoped_refptr<SyncContext> context(sync_context());
- if (WaitForSingleObject(context->shutdown_event(), 0) == WAIT_OBJECT_0) {
+ if (context->shutdown_event()->IsSignaled()) {
delete message;
return false;
}
@@ -390,7 +395,7 @@ bool SyncChannel::SendWithTimeout(Message* message, int timeout_ms) {
SyncMessage* sync_msg = static_cast<SyncMessage*>(message);
context->Push(sync_msg);
int message_id = SyncMessage::GetMessageId(*sync_msg);
- HANDLE pump_messages_event = sync_msg->pump_messages_event();
+ WaitableEvent* pump_messages_event = sync_msg->pump_messages_event();
ChannelProxy::Send(message);
@@ -409,22 +414,25 @@ bool SyncChannel::SendWithTimeout(Message* message, int timeout_ms) {
return context->Pop();
}
-void SyncChannel::WaitForReply(HANDLE pump_messages_event) {
+void SyncChannel::WaitForReply(WaitableEvent* pump_messages_event) {
while (true) {
- HANDLE objects[] = { sync_context()->GetDispatchEvent(),
- sync_context()->GetSendDoneEvent(),
- pump_messages_event };
- uint32 count = pump_messages_event ? 3: 2;
- DWORD result = WaitForMultipleObjects(count, objects, FALSE, INFINITE);
- if (result == WAIT_OBJECT_0) {
+ WaitableEvent* objects[] = {
+ sync_context()->GetDispatchEvent(),
+ sync_context()->GetSendDoneEvent(),
+ pump_messages_event
+ };
+
+ unsigned count = pump_messages_event ? 3: 2;
+ unsigned result = WaitableEvent::WaitMany(objects, count);
+ if (result == 0 /* dispatch event */) {
// We're waiting for a reply, but we received a blocking synchronous
// call. We must process it or otherwise a deadlock might occur.
- ResetEvent(sync_context()->GetDispatchEvent());
+ sync_context()->GetDispatchEvent()->Reset();
sync_context()->DispatchMessages();
continue;
}
- if (result == WAIT_OBJECT_0 + 2)
+ if (result == 2 /* pump_messages_event */)
WaitForReplyWithNestedMessageLoop(); // Start a nested message loop.
break;
@@ -432,7 +440,7 @@ void SyncChannel::WaitForReply(HANDLE pump_messages_event) {
}
void SyncChannel::WaitForReplyWithNestedMessageLoop() {
- HANDLE old_done_event = send_done_watcher_.GetWatchedObject();
+ WaitableEvent* old_done_event = send_done_watcher_.GetWatchedEvent();
send_done_watcher_.StopWatching();
send_done_watcher_.StartWatching(sync_context()->GetSendDoneEvent(), this);
bool old_state = MessageLoop::current()->NestableTasksAllowed();
@@ -443,17 +451,17 @@ void SyncChannel::WaitForReplyWithNestedMessageLoop() {
send_done_watcher_.StartWatching(old_done_event, this);
}
-void SyncChannel::OnObjectSignaled(HANDLE object) {
- HANDLE dispatch_event = sync_context()->GetDispatchEvent();
- if (object == dispatch_event) {
+void SyncChannel::OnWaitableEventSignaled(WaitableEvent* event) {
+ WaitableEvent* dispatch_event = sync_context()->GetDispatchEvent();
+ if (event == dispatch_event) {
// The call to DispatchMessages might delete this object, so reregister
// the object watcher first.
- ResetEvent(dispatch_event);
+ dispatch_event->Reset();
dispatch_watcher_.StartWatching(dispatch_event, this);
sync_context()->DispatchMessages();
} else {
// We got the reply, timed out or the process shutdown.
- DCHECK(object == sync_context()->GetSendDoneEvent());
+ DCHECK(event == sync_context()->GetSendDoneEvent());
MessageLoop::current()->Quit();
}
}
« no previous file with comments | « chrome/common/ipc_sync_channel.h ('k') | chrome/common/ipc_sync_message.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698