diff options
author | erikchen <erikchen@chromium.org> | 2015-07-27 13:28:20 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-07-27 20:29:06 +0000 |
commit | c04ab34c84e272a6bd7234f14bcf9950a346c580 (patch) | |
tree | c860b9dee6015d90bed92cfd0943b1cf23d68cae /ipc/ipc_channel_win.cc | |
parent | ba53d6dc1d33f3be64defce3e72cf6c0c5cd855a (diff) | |
download | chromium_src-c04ab34c84e272a6bd7234f14bcf9950a346c580.zip chromium_src-c04ab34c84e272a6bd7234f14bcf9950a346c580.tar.gz chromium_src-c04ab34c84e272a6bd7234f14bcf9950a346c580.tar.bz2 |
ipc: Add attachment broker code for the privileged browser process.
No intended behavior change.
This CL adds the class AttachmentBrokerPrivilegedWin, a subclass of
AttachmentBroker intended for use in the privileged browser process on the
Windows platform. No brokerable attachments are made outside of tests, so this
code is not yet active.
This CL consists of several changes:
- The class AttachmentBrokerPrivilegedWin was created.
- Common logic between AttachmentBrokerPrivilegedWin and AttachmentBrokerWin
was moved to AttachmentBroker.
- ChannelWin was given a new member prelim_queue_. This queue is normally
empty, but in some circumstances messages are queued here before being
processed for delivery. See the documentation for a full explanation.
BUG=466437
Review URL: https://codereview.chromium.org/1246103006
Cr-Commit-Position: refs/heads/master@{#340548}
Diffstat (limited to 'ipc/ipc_channel_win.cc')
-rw-r--r-- | ipc/ipc_channel_win.cc | 47 |
1 files changed, 41 insertions, 6 deletions
diff --git a/ipc/ipc_channel_win.cc b/ipc/ipc_channel_win.cc index 0a905a8..a01a272 100644 --- a/ipc/ipc_channel_win.cc +++ b/ipc/ipc_channel_win.cc @@ -81,23 +81,38 @@ void ChannelWin::Close() { } bool ChannelWin::Send(Message* message) { - // TODO(erikchen): Remove this DCHECK once ChannelWin fully supports - // brokerable attachments. http://crbug.com/493414. - DCHECK(!message->HasAttachments()); DCHECK(thread_check_->CalledOnValidThread()); DVLOG(2) << "sending message @" << message << " on channel @" << this << " with type " << message->type() << " (" << output_queue_.size() << " in queue)"; + if (!prelim_queue_.empty()) { + prelim_queue_.push(message); + return true; + } + + if (message->HasBrokerableAttachments() && + peer_pid_ == base::kNullProcessId) { + prelim_queue_.push(message); + return true; + } + + return ProcessMessageForDelivery(message); +} + +bool ChannelWin::ProcessMessageForDelivery(Message* message) { // Sending a brokerable attachment requires a call to Channel::Send(), so - // Send() may be re-entrant. Brokered attachments must be sent before the - // Message itself. + // both Send() and ProcessMessageForDelivery() may be re-entrant. Brokered + // attachments must be sent before the Message itself. if (message->HasBrokerableAttachments()) { DCHECK(broker_); + DCHECK(peer_pid_ != base::kNullProcessId); for (const BrokerableAttachment* attachment : message->attachment_set()->PeekBrokerableAttachments()) { - if (!broker_->SendAttachmentToProcess(attachment, peer_pid_)) + if (!broker_->SendAttachmentToProcess(attachment, peer_pid_)) { + delete message; return false; + } } } @@ -106,6 +121,8 @@ bool ChannelWin::Send(Message* message) { #endif message->TraceMessageBegin(); + + // |output_queue_| takes ownership of |message|. output_queue_.push(message); // ensure waiting to write if (!waiting_connect_) { @@ -118,6 +135,21 @@ bool ChannelWin::Send(Message* message) { return true; } +void ChannelWin::FlushPrelimQueue() { + DCHECK_NE(peer_pid_, base::kNullProcessId); + + // Due to the possibly re-entrant nature of ProcessMessageForDelivery(), it + // is critical that |prelim_queue_| appears empty. + std::queue<Message*> prelim_queue; + prelim_queue_.swap(prelim_queue); + + while (!prelim_queue.empty()) { + Message* m = prelim_queue.front(); + ProcessMessageForDelivery(m); + prelim_queue.pop(); + } +} + AttachmentBroker* ChannelWin::GetAttachmentBroker() { return broker_; } @@ -205,6 +237,9 @@ void ChannelWin::HandleInternalMessage(const Message& msg) { peer_pid_ = claimed_pid; // Validation completed. validate_client_ = false; + + FlushPrelimQueue(); + listener()->OnChannelConnected(claimed_pid); } |