Index: chrome/common/ipc_channel_posix.cc |
=================================================================== |
--- chrome/common/ipc_channel_posix.cc (revision 6915) |
+++ chrome/common/ipc_channel_posix.cc (working copy) |
@@ -6,17 +6,11 @@ |
#include <errno.h> |
#include <fcntl.h> |
-#include <stddef.h> |
#include <sys/types.h> |
#include <sys/socket.h> |
#include <sys/stat.h> |
-#if defined(OS_LINUX) |
-#include <linux/un.h> |
-#elif defined(OS_MACOSX) |
-#include <sys/un.h> |
-#endif |
+#include <stddef.h> |
- |
#include "base/logging.h" |
#include "base/process_util.h" |
#include "base/scoped_ptr.h" |
@@ -24,6 +18,12 @@ |
#include "chrome/common/chrome_counters.h" |
#include "chrome/common/ipc_message_utils.h" |
+#if defined(OS_LINUX) |
+#include <linux/un.h> |
+#elif defined(OS_MACOSX) |
+#include <sys/un.h> |
+#endif |
+ |
namespace IPC { |
//------------------------------------------------------------------------------ |
@@ -150,7 +150,9 @@ |
Channel::ChannelImpl::ChannelImpl(const std::wstring& channel_id, Mode mode, |
Listener* listener) |
: mode_(mode), |
- is_blocked_on_write_(false), |
+ server_listen_connection_event_(new EventHolder()), |
+ read_event_(new EventHolder()), |
+ write_event_(new EventHolder()), |
message_send_bytes_written_(0), |
server_listen_pipe_(-1), |
pipe_(-1), |
@@ -212,22 +214,21 @@ |
if (server_listen_pipe_ == -1) { |
return false; |
} |
- MessageLoopForIO::current()->WatchFileDescriptor( |
- server_listen_pipe_, |
- true, |
- MessageLoopForIO::WATCH_READ, |
- &server_listen_connection_watcher_, |
- this); |
+ event *ev = &(server_listen_connection_event_->event); |
+ MessageLoopForIO::current()->WatchFileHandle(server_listen_pipe_, |
+ EV_READ | EV_PERSIST, |
+ ev, |
+ this); |
+ server_listen_connection_event_->is_active = true; |
} else { |
if (pipe_ == -1) { |
return false; |
} |
- MessageLoopForIO::current()->WatchFileDescriptor( |
- pipe_, |
- true, |
- MessageLoopForIO::WATCH_READ, |
- &read_watcher_, |
- this); |
+ MessageLoopForIO::current()->WatchFileHandle(pipe_, |
+ EV_READ | EV_PERSIST, |
+ &(read_event_->event), |
+ this); |
+ read_event_->is_active = true; |
waiting_connect_ = false; |
} |
@@ -316,7 +317,6 @@ |
bool Channel::ChannelImpl::ProcessOutgoingMessages() { |
DCHECK(!waiting_connect_); // Why are we trying to send messages if there's |
// no connection? |
- is_blocked_on_write_ = false; |
if (output_queue_.empty()) |
return true; |
@@ -324,6 +324,15 @@ |
if (pipe_ == -1) |
return false; |
+ // If libevent was monitoring the socket for us (we blocked when trying to |
+ // write a message last time), then delete the underlying libevent structure. |
+ if (write_event_->is_active) { |
+ // TODO(playmobil): This calls event_del(), but we can probably |
+ // do with just calling event_add here. |
+ MessageLoopForIO::current()->UnwatchFileHandle(&(write_event_->event)); |
+ write_event_->is_active = false; |
+ } |
+ |
// Write out all the messages we can till the write blocks or there are no |
// more outgoing messages. |
while (!output_queue_.empty()) { |
@@ -346,13 +355,12 @@ |
message_send_bytes_written_ += bytes_written; |
// Tell libevent to call us back once things are unblocked. |
- is_blocked_on_write_ = true; |
- MessageLoopForIO::current()->WatchFileDescriptor( |
- pipe_, |
- false, // One shot |
- MessageLoopForIO::WATCH_WRITE, |
- &write_watcher_, |
- this); |
+ MessageLoopForIO::current()->WatchFileHandle(server_listen_pipe_, |
+ EV_WRITE, |
+ &(write_event_->event), |
+ this); |
+ write_event_->is_active = true; |
+ |
} else { |
message_send_bytes_written_ = 0; |
@@ -383,7 +391,7 @@ |
output_queue_.push(message); |
if (!waiting_connect_) { |
- if (!is_blocked_on_write_) { |
+ if (!write_event_->is_active) { |
if (!ProcessOutgoingMessages()) |
return false; |
} |
@@ -393,7 +401,7 @@ |
} |
// Called by libevent when we can read from th pipe without blocking. |
-void Channel::ChannelImpl::OnFileCanReadWithoutBlocking(int fd) { |
+void Channel::ChannelImpl::OnFileReadReady(int fd) { |
bool send_server_hello_msg = false; |
if (waiting_connect_ && mode_ == MODE_SERVER) { |
if (!ServerAcceptFifoConnection(server_listen_pipe_, &pipe_)) { |
@@ -402,16 +410,16 @@ |
// No need to watch the listening socket any longer since only one client |
// can connect. So unregister with libevent. |
- server_listen_connection_watcher_.StopWatchingFileDescriptor(); |
+ event *ev = &(server_listen_connection_event_->event); |
+ MessageLoopForIO::current()->UnwatchFileHandle(ev); |
+ server_listen_connection_event_->is_active = false; |
// Start watching our end of the socket. |
- MessageLoopForIO::current()->WatchFileDescriptor( |
- pipe_, |
- true, |
- MessageLoopForIO::WATCH_READ, |
- &read_watcher_, |
- this); |
- |
+ MessageLoopForIO::current()->WatchFileHandle(pipe_, |
+ EV_READ | EV_PERSIST, |
+ &(read_event_->event), |
+ this); |
+ read_event_->is_active = true; |
waiting_connect_ = false; |
send_server_hello_msg = true; |
} |
@@ -428,14 +436,12 @@ |
// This gives us a chance to kill the client if the incoming handshake |
// is invalid. |
if (send_server_hello_msg) { |
- // This should be our first write so there' sno chance we can block here... |
- DCHECK(is_blocked_on_write_ == false); |
ProcessOutgoingMessages(); |
} |
} |
// Called by libevent when we can write to the pipe without blocking. |
-void Channel::ChannelImpl::OnFileCanWriteWithoutBlocking(int fd) { |
+void Channel::ChannelImpl::OnFileWriteReady(int fd) { |
if (!ProcessOutgoingMessages()) { |
Close(); |
listener_->OnChannelError(); |
@@ -447,7 +453,11 @@ |
// idempotent. |
// Unregister libevent for the listening socket and close it. |
- server_listen_connection_watcher_.StopWatchingFileDescriptor(); |
+ if (server_listen_connection_event_ && |
+ server_listen_connection_event_->is_active) { |
+ MessageLoopForIO::current()->UnwatchFileHandle( |
+ &(server_listen_connection_event_->event)); |
+ } |
if (server_listen_pipe_ != -1) { |
close(server_listen_pipe_); |
@@ -455,13 +465,24 @@ |
} |
// Unregister libevent for the FIFO and close it. |
- read_watcher_.StopWatchingFileDescriptor(); |
- write_watcher_.StopWatchingFileDescriptor(); |
+ if (read_event_ && read_event_->is_active) { |
+ MessageLoopForIO::current()->UnwatchFileHandle(&(read_event_->event)); |
+ } |
+ if (write_event_ && write_event_->is_active) { |
+ MessageLoopForIO::current()->UnwatchFileHandle(&(write_event_->event)); |
+ } |
if (pipe_ != -1) { |
close(pipe_); |
pipe_ = -1; |
} |
+ delete server_listen_connection_event_; |
+ server_listen_connection_event_ = NULL; |
+ delete read_event_; |
+ read_event_ = NULL; |
+ delete write_event_; |
+ write_event_ = NULL; |
+ |
// Unlink the FIFO |
unlink(pipe_name_.c_str()); |