OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ipc/ipc_channel_proxy.h" | 5 #include "ipc/ipc_channel_proxy.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <utility> | 10 #include <utility> |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 #ifdef IPC_MESSAGE_LOG_ENABLED | 108 #ifdef IPC_MESSAGE_LOG_ENABLED |
109 if (logger->Enabled()) | 109 if (logger->Enabled()) |
110 logger->OnPostDispatchMessage(message, channel_id_); | 110 logger->OnPostDispatchMessage(message, channel_id_); |
111 #endif | 111 #endif |
112 return true; | 112 return true; |
113 } | 113 } |
114 return false; | 114 return false; |
115 } | 115 } |
116 | 116 |
117 // Called on the IPC::Channel thread | 117 // Called on the IPC::Channel thread |
| 118 void ChannelProxy::Context::UnpauseChannel(bool flush) { |
| 119 DCHECK(channel_); |
| 120 channel_->Unpause(flush); |
| 121 } |
| 122 |
| 123 // Called on the IPC::Channel thread |
| 124 void ChannelProxy::Context::FlushChannel() { |
| 125 DCHECK(channel_); |
| 126 channel_->Flush(); |
| 127 } |
| 128 |
| 129 // Called on the IPC::Channel thread |
118 bool ChannelProxy::Context::OnMessageReceived(const Message& message) { | 130 bool ChannelProxy::Context::OnMessageReceived(const Message& message) { |
119 // First give a chance to the filters to process this message. | 131 // First give a chance to the filters to process this message. |
120 if (!TryFilters(message)) | 132 if (!TryFilters(message)) |
121 OnMessageReceivedNoFilter(message); | 133 OnMessageReceivedNoFilter(message); |
122 return true; | 134 return true; |
123 } | 135 } |
124 | 136 |
125 // Called on the IPC::Channel thread | 137 // Called on the IPC::Channel thread |
126 bool ChannelProxy::Context::OnMessageReceivedNoFilter(const Message& message) { | 138 bool ChannelProxy::Context::OnMessageReceivedNoFilter(const Message& message) { |
127 listener_task_runner_->PostTask( | 139 listener_task_runner_->PostTask( |
(...skipping 24 matching lines...) Expand all Loading... |
152 void ChannelProxy::Context::OnChannelError() { | 164 void ChannelProxy::Context::OnChannelError() { |
153 for (size_t i = 0; i < filters_.size(); ++i) | 165 for (size_t i = 0; i < filters_.size(); ++i) |
154 filters_[i]->OnChannelError(); | 166 filters_[i]->OnChannelError(); |
155 | 167 |
156 // See above comment about using listener_task_runner_ here. | 168 // See above comment about using listener_task_runner_ here. |
157 listener_task_runner_->PostTask( | 169 listener_task_runner_->PostTask( |
158 FROM_HERE, base::Bind(&Context::OnDispatchError, this)); | 170 FROM_HERE, base::Bind(&Context::OnDispatchError, this)); |
159 } | 171 } |
160 | 172 |
161 // Called on the IPC::Channel thread | 173 // Called on the IPC::Channel thread |
162 void ChannelProxy::Context::OnChannelOpened() { | 174 void ChannelProxy::Context::OnChannelOpened(bool pause) { |
163 DCHECK(channel_ != NULL); | 175 DCHECK(channel_ != NULL); |
164 | 176 |
165 // Assume a reference to ourselves on behalf of this thread. This reference | 177 // Assume a reference to ourselves on behalf of this thread. This reference |
166 // will be released when we are closed. | 178 // will be released when we are closed. |
167 AddRef(); | 179 AddRef(); |
168 | 180 |
169 if (!channel_->Connect()) { | 181 bool success = pause ? channel_->ConnectPaused() : channel_->Connect(); |
| 182 if (!success) { |
170 OnChannelError(); | 183 OnChannelError(); |
171 return; | 184 return; |
172 } | 185 } |
173 | 186 |
174 for (size_t i = 0; i < filters_.size(); ++i) | 187 for (size_t i = 0; i < filters_.size(); ++i) |
175 filters_[i]->OnFilterAdded(channel_.get()); | 188 filters_[i]->OnFilterAdded(channel_.get()); |
176 } | 189 } |
177 | 190 |
178 // Called on the IPC::Channel thread | 191 // Called on the IPC::Channel thread |
179 void ChannelProxy::Context::OnChannelClosed() { | 192 void ChannelProxy::Context::OnChannelClosed() { |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
455 } | 468 } |
456 | 469 |
457 ChannelProxy::~ChannelProxy() { | 470 ChannelProxy::~ChannelProxy() { |
458 DCHECK(CalledOnValidThread()); | 471 DCHECK(CalledOnValidThread()); |
459 | 472 |
460 Close(); | 473 Close(); |
461 } | 474 } |
462 | 475 |
463 void ChannelProxy::Init(const IPC::ChannelHandle& channel_handle, | 476 void ChannelProxy::Init(const IPC::ChannelHandle& channel_handle, |
464 Channel::Mode mode, | 477 Channel::Mode mode, |
465 bool create_pipe_now) { | 478 bool create_pipe_now, |
| 479 bool create_paused) { |
466 #if defined(OS_POSIX) | 480 #if defined(OS_POSIX) |
467 // When we are creating a server on POSIX, we need its file descriptor | 481 // When we are creating a server on POSIX, we need its file descriptor |
468 // to be created immediately so that it can be accessed and passed | 482 // to be created immediately so that it can be accessed and passed |
469 // to other processes. Forcing it to be created immediately avoids | 483 // to other processes. Forcing it to be created immediately avoids |
470 // race conditions that may otherwise arise. | 484 // race conditions that may otherwise arise. |
471 if (mode & Channel::MODE_SERVER_FLAG) { | 485 if (mode & Channel::MODE_SERVER_FLAG) { |
472 create_pipe_now = true; | 486 create_pipe_now = true; |
473 } | 487 } |
474 #endif // defined(OS_POSIX) | 488 #endif // defined(OS_POSIX) |
475 Init( | 489 Init( |
476 ChannelFactory::Create(channel_handle, mode, context_->ipc_task_runner()), | 490 ChannelFactory::Create(channel_handle, mode, context_->ipc_task_runner()), |
477 create_pipe_now); | 491 create_pipe_now, create_paused); |
478 } | 492 } |
479 | 493 |
480 void ChannelProxy::Init(std::unique_ptr<ChannelFactory> factory, | 494 void ChannelProxy::Init(std::unique_ptr<ChannelFactory> factory, |
481 bool create_pipe_now) { | 495 bool create_pipe_now, |
| 496 bool create_paused) { |
482 DCHECK(CalledOnValidThread()); | 497 DCHECK(CalledOnValidThread()); |
483 DCHECK(!did_init_); | 498 DCHECK(!did_init_); |
484 | 499 |
485 if (create_pipe_now) { | 500 if (create_pipe_now) { |
486 // Create the channel immediately. This effectively sets up the | 501 // Create the channel immediately. This effectively sets up the |
487 // low-level pipe so that the client can connect. Without creating | 502 // low-level pipe so that the client can connect. Without creating |
488 // the pipe immediately, it is possible for a listener to attempt | 503 // the pipe immediately, it is possible for a listener to attempt |
489 // to connect and get an error since the pipe doesn't exist yet. | 504 // to connect and get an error since the pipe doesn't exist yet. |
490 context_->CreateChannel(std::move(factory)); | 505 context_->CreateChannel(std::move(factory)); |
491 } else { | 506 } else { |
492 context_->ipc_task_runner()->PostTask( | 507 context_->ipc_task_runner()->PostTask( |
493 FROM_HERE, base::Bind(&Context::CreateChannel, context_, | 508 FROM_HERE, base::Bind(&Context::CreateChannel, context_, |
494 base::Passed(&factory))); | 509 base::Passed(&factory))); |
495 } | 510 } |
496 | 511 |
497 // complete initialization on the background thread | 512 // complete initialization on the background thread |
498 context_->ipc_task_runner()->PostTask( | 513 context_->ipc_task_runner()->PostTask( |
499 FROM_HERE, base::Bind(&Context::OnChannelOpened, context_)); | 514 FROM_HERE, |
| 515 base::Bind(&Context::OnChannelOpened, context_, create_paused)); |
500 | 516 |
501 did_init_ = true; | 517 did_init_ = true; |
502 OnChannelInit(); | 518 OnChannelInit(); |
503 } | 519 } |
504 | 520 |
| 521 void ChannelProxy::Unpause(bool flush) { |
| 522 context_->ipc_task_runner()->PostTask( |
| 523 FROM_HERE, base::Bind(&Context::UnpauseChannel, context_, flush)); |
| 524 } |
| 525 |
| 526 void ChannelProxy::Flush() { |
| 527 context_->ipc_task_runner()->PostTask( |
| 528 FROM_HERE, base::Bind(&Context::FlushChannel, context_)); |
| 529 } |
| 530 |
505 void ChannelProxy::Close() { | 531 void ChannelProxy::Close() { |
506 DCHECK(CalledOnValidThread()); | 532 DCHECK(CalledOnValidThread()); |
507 | 533 |
508 // Clear the backpointer to the listener so that any pending calls to | 534 // Clear the backpointer to the listener so that any pending calls to |
509 // Context::OnDispatchMessage or OnDispatchError will be ignored. It is | 535 // Context::OnDispatchMessage or OnDispatchError will be ignored. It is |
510 // possible that the channel could be closed while it is receiving messages! | 536 // possible that the channel could be closed while it is receiving messages! |
511 context_->Clear(); | 537 context_->Clear(); |
512 | 538 |
513 if (context_->ipc_task_runner()) { | 539 if (context_->ipc_task_runner()) { |
514 context_->ipc_task_runner()->PostTask( | 540 context_->ipc_task_runner()->PostTask( |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 return channel->TakeClientFileDescriptor(); | 640 return channel->TakeClientFileDescriptor(); |
615 } | 641 } |
616 #endif | 642 #endif |
617 | 643 |
618 void ChannelProxy::OnChannelInit() { | 644 void ChannelProxy::OnChannelInit() { |
619 } | 645 } |
620 | 646 |
621 //----------------------------------------------------------------------------- | 647 //----------------------------------------------------------------------------- |
622 | 648 |
623 } // namespace IPC | 649 } // namespace IPC |
OLD | NEW |