summaryrefslogtreecommitdiffstats
path: root/chrome/common/ipc_channel.cc
diff options
context:
space:
mode:
authorrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-10-13 19:19:36 +0000
committerrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-10-13 19:19:36 +0000
commitc1afbd2c74edf09456ce6a747d4a0a8f746a6685 (patch)
treef8f76297e6b26ab81811158daee61a66d6c7c962 /chrome/common/ipc_channel.cc
parent2dd6eb4df9d17a30e7a59a44ba5fbaa7c0046466 (diff)
downloadchromium_src-c1afbd2c74edf09456ce6a747d4a0a8f746a6685.zip
chromium_src-c1afbd2c74edf09456ce6a747d4a0a8f746a6685.tar.gz
chromium_src-c1afbd2c74edf09456ce6a747d4a0a8f746a6685.tar.bz2
Remove WatchObject from the ipc channel.
Review URL: http://codereview.chromium.org/6031 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3301 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/common/ipc_channel.cc')
-rw-r--r--chrome/common/ipc_channel.cc129
1 files changed, 57 insertions, 72 deletions
diff --git a/chrome/common/ipc_channel.cc b/chrome/common/ipc_channel.cc
index c87d75f..8c0612e 100644
--- a/chrome/common/ipc_channel.cc
+++ b/chrome/common/ipc_channel.cc
@@ -2,14 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "chrome/common/ipc_channel.h"
+
#include <windows.h>
#include <sstream>
-#include "chrome/common/chrome_counters.h"
-#include "chrome/common/ipc_channel.h"
-
+#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/win_util.h"
+#include "chrome/common/chrome_counters.h"
#include "chrome/common/ipc_logging.h"
#include "chrome/common/ipc_message_utils.h"
@@ -39,7 +40,8 @@ Channel::Channel(const wstring& channel_id, Mode mode, Listener* listener)
: pipe_(INVALID_HANDLE_VALUE),
listener_(listener),
waiting_connect_(mode == MODE_SERVER),
- processing_incoming_(false) {
+ processing_incoming_(false),
+ ALLOW_THIS_IN_INITIALIZER_LIST(factory_(this)) {
if (!CreatePipe(channel_id, mode)) {
// The pipe may have been closed already.
LOG(WARNING) << "Unable to create pipe named \"" << channel_id <<
@@ -81,11 +83,8 @@ bool Channel::Send(Message* message) {
// ensure waiting to write
if (!waiting_connect_) {
if (!output_state_.is_pending) {
- if (!ProcessOutgoingMessages())
+ if (!ProcessOutgoingMessages(NULL, 0))
return false;
- } else if (WaitForSingleObject(output_state_.overlapped.hEvent, 0) ==
- WAIT_OBJECT_0) {
- OnObjectSignaled(output_state_.overlapped.hEvent);
}
}
@@ -158,30 +157,31 @@ bool Channel::Connect() {
if (pipe_ == INVALID_HANDLE_VALUE)
return false;
+ MessageLoopForIO::current()->RegisterIOHandler(pipe_, this);
+
// Check to see if there is a client connected to our pipe...
if (waiting_connect_)
ProcessConnection();
if (!input_state_.is_pending) {
- // complete setup asynchronously. to do that, we force the input state
- // to be signaled, which will cause us to be called back from the event
- // queue. by not setting input_state_.is_pending to true, we indicate
- // to OnObjectSignaled that this is the special initialization signal.
-
- SetEvent(input_state_.overlapped.hEvent);
- MessageLoopForIO::current()->WatchObject(
- input_state_.overlapped.hEvent, this);
+ // Complete setup asynchronously. By not setting input_state_.is_pending
+ // to true, we indicate to OnIOCompleted that this is the special
+ // initialization signal.
+ MessageLoopForIO::current()->PostTask(FROM_HERE, factory_.NewRunnableMethod(
+ &Channel::OnIOCompleted, &input_state_.overlapped, 0, 0));
}
if (!waiting_connect_)
- ProcessOutgoingMessages();
+ ProcessOutgoingMessages(NULL, 0);
return true;
}
bool Channel::ProcessConnection() {
- input_state_.is_pending = false;
- MessageLoopForIO::current()->WatchObject(
- input_state_.overlapped.hEvent, NULL);
+ if (input_state_.is_pending) {
+ input_state_.is_pending = false;
+ MessageLoopForIO::current()->RegisterIOContext(&input_state_.overlapped,
+ NULL);
+ }
// Do we have a client connected to our pipe?
DCHECK(pipe_ != INVALID_HANDLE_VALUE);
@@ -198,8 +198,8 @@ bool Channel::ProcessConnection() {
switch (err) {
case ERROR_IO_PENDING:
input_state_.is_pending = true;
- MessageLoopForIO::current()->WatchObject(
- input_state_.overlapped.hEvent, this);
+ MessageLoopForIO::current()->RegisterIOContext(&input_state_.overlapped,
+ this);
break;
case ERROR_PIPE_CONNECTED:
waiting_connect_ = false;
@@ -212,34 +212,24 @@ bool Channel::ProcessConnection() {
return true;
}
-bool Channel::ProcessIncomingMessages() {
- DWORD bytes_read = 0;
-
- MessageLoopForIO::current()->WatchObject(
- input_state_.overlapped.hEvent, NULL);
-
+bool Channel::ProcessIncomingMessages(OVERLAPPED* context,
+ DWORD bytes_read) {
if (input_state_.is_pending) {
input_state_.is_pending = false;
+ DCHECK(context);
+ MessageLoopForIO::current()->RegisterIOContext(&input_state_.overlapped,
+ NULL);
- BOOL ok = GetOverlappedResult(pipe_,
- &input_state_.overlapped,
- &bytes_read,
- FALSE);
- if (!ok || bytes_read == 0) {
- DWORD err = GetLastError();
- // TODO(pkasting): http://b/119851 We can get ERR_BROKEN_PIPE here if the
- // renderer crashes. We should handle this cleanly.
- LOG(ERROR) << "pipe error: " << err;
+ if (!context || !bytes_read)
return false;
- }
} else {
- // this happens at channel initialization
- ResetEvent(input_state_.overlapped.hEvent);
+ // This happens at channel initialization.
+ DCHECK(!bytes_read && context == &input_state_.overlapped);
}
for (;;) {
if (bytes_read == 0) {
- // read from pipe...
+ // Read from pipe...
BOOL ok = ReadFile(pipe_,
input_buf_,
BUF_SIZE,
@@ -248,8 +238,8 @@ bool Channel::ProcessIncomingMessages() {
if (!ok) {
DWORD err = GetLastError();
if (err == ERROR_IO_PENDING) {
- MessageLoopForIO::current()->WatchObject(
- input_state_.overlapped.hEvent, this);
+ MessageLoopForIO::current()->RegisterIOContext(
+ &input_state_.overlapped, this);
input_state_.is_pending = true;
return true;
}
@@ -259,7 +249,7 @@ bool Channel::ProcessIncomingMessages() {
}
DCHECK(bytes_read);
- // process messages from input buffer
+ // Process messages from input buffer.
const char* p, *end;
if (input_overflow_buf_.empty()) {
@@ -282,8 +272,8 @@ bool Channel::ProcessIncomingMessages() {
int len = static_cast<int>(message_tail - p);
const Message m(p, len);
#ifdef IPC_MESSAGE_DEBUG_EXTRA
- DLOG(INFO) << "received message on channel @" << this << " with type " <<
- m.type();
+ DLOG(INFO) << "received message on channel @" << this <<
+ " with type " << m.type();
#endif
if (m.routing_id() == MSG_ROUTING_NONE &&
m.type() == HELLO_MESSAGE_TYPE) {
@@ -294,37 +284,34 @@ bool Channel::ProcessIncomingMessages() {
}
p = message_tail;
} else {
- // last message is partial
+ // Last message is partial.
break;
}
}
input_overflow_buf_.assign(p, end - p);
- bytes_read = 0; // get more data
+ bytes_read = 0; // Get more data.
}
return true;
}
-bool Channel::ProcessOutgoingMessages() {
+bool Channel::ProcessOutgoingMessages(OVERLAPPED* context,
+ DWORD bytes_written) {
DCHECK(!waiting_connect_); // Why are we trying to send messages if there's
// no connection?
- DWORD bytes_written;
if (output_state_.is_pending) {
- MessageLoopForIO::current()->WatchObject(
- output_state_.overlapped.hEvent, NULL);
+ DCHECK(context);
+ MessageLoopForIO::current()->RegisterIOContext(&output_state_.overlapped,
+ NULL);
output_state_.is_pending = false;
- BOOL ok = GetOverlappedResult(pipe_,
- &output_state_.overlapped,
- &bytes_written,
- FALSE);
- if (!ok || bytes_written == 0) {
+ if (!context || bytes_written == 0) {
DWORD err = GetLastError();
LOG(ERROR) << "pipe error: " << err;
return false;
}
- // message was sent
+ // Message was sent.
DCHECK(!output_queue_.empty());
Message* m = output_queue_.front();
output_queue_.pop();
@@ -332,7 +319,7 @@ bool Channel::ProcessOutgoingMessages() {
}
while (!output_queue_.empty()) {
- // write to pipe...
+ // Write to pipe...
Message* m = output_queue_.front();
BOOL ok = WriteFile(pipe_,
m->data(),
@@ -342,13 +329,13 @@ bool Channel::ProcessOutgoingMessages() {
if (!ok) {
DWORD err = GetLastError();
if (err == ERROR_IO_PENDING) {
- MessageLoopForIO::current()->WatchObject(
- output_state_.overlapped.hEvent, this);
+ MessageLoopForIO::current()->RegisterIOContext(
+ &output_state_.overlapped, this);
output_state_.is_pending = true;
#ifdef IPC_MESSAGE_DEBUG_EXTRA
- DLOG(INFO) << "sent pending message @" << m << " on channel @" << this <<
- " with type " << m->type();
+ DLOG(INFO) << "sent pending message @" << m << " on channel @" <<
+ this << " with type " << m->type();
#endif
return true;
@@ -406,14 +393,15 @@ bool Channel::ProcessPendingMessages(DWORD max_wait_msec) {
#endif
}
-void Channel::OnObjectSignaled(HANDLE object) {
+void Channel::OnIOCompleted(OVERLAPPED* context, DWORD bytes_transfered,
+ DWORD error) {
bool ok;
- if (object == input_state_.overlapped.hEvent) {
+ if (context == &input_state_.overlapped) {
if (waiting_connect_) {
ProcessConnection();
// We may have some messages queued up to send...
if (!output_queue_.empty() && !output_state_.is_pending)
- ProcessOutgoingMessages();
+ ProcessOutgoingMessages(NULL, 0);
if (input_state_.is_pending)
return;
// else, fall-through and look for incoming messages...
@@ -421,11 +409,11 @@ void Channel::OnObjectSignaled(HANDLE object) {
// we don't support recursion through OnMessageReceived yet!
DCHECK(!processing_incoming_);
processing_incoming_ = true;
- ok = ProcessIncomingMessages();
+ ok = ProcessIncomingMessages(context, bytes_transfered);
processing_incoming_ = false;
} else {
- DCHECK(object == output_state_.overlapped.hEvent);
- ok = ProcessOutgoingMessages();
+ DCHECK(context == &output_state_.overlapped);
+ ok = ProcessOutgoingMessages(context, bytes_transfered);
}
if (!ok) {
Close();
@@ -433,7 +421,4 @@ void Channel::OnObjectSignaled(HANDLE object) {
}
}
-//------------------------------------------------------------------------------
-
}
-