Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/mojo/ipc_channel_mojo.h" | 5 #include "ipc/mojo/ipc_channel_mojo.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
| 10 #include "ipc/ipc_listener.h" | 10 #include "ipc/ipc_listener.h" |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 168 void ChannelMojo::ChannelInfoDeleter::operator()( | 168 void ChannelMojo::ChannelInfoDeleter::operator()( |
| 169 mojo::embedder::ChannelInfo* ptr) const { | 169 mojo::embedder::ChannelInfo* ptr) const { |
| 170 mojo::embedder::DestroyChannel(ptr); | 170 mojo::embedder::DestroyChannel(ptr); |
| 171 } | 171 } |
| 172 | 172 |
| 173 //------------------------------------------------------------------------------ | 173 //------------------------------------------------------------------------------ |
| 174 | 174 |
| 175 // static | 175 // static |
| 176 bool ChannelMojo::ShouldBeUsed() { | 176 bool ChannelMojo::ShouldBeUsed() { |
| 177 // TODO(morrita): Turn this on for a set of platforms. | 177 // TODO(morrita): Turn this on for a set of platforms. |
| 178 return false; | 178 return true; |
|
Hajime Morrita
2014/12/05 02:54:09
I do this just for exercising tests. No intention
| |
| 179 } | 179 } |
| 180 | 180 |
| 181 // static | 181 // static |
| 182 scoped_ptr<ChannelMojo> ChannelMojo::Create(ChannelMojo::Delegate* delegate, | 182 scoped_ptr<ChannelMojo> ChannelMojo::Create(ChannelMojo::Delegate* delegate, |
| 183 const ChannelHandle& channel_handle, | 183 const ChannelHandle& channel_handle, |
| 184 Mode mode, | 184 Mode mode, |
| 185 Listener* listener) { | 185 Listener* listener) { |
| 186 switch (mode) { | 186 switch (mode) { |
| 187 case Channel::MODE_CLIENT: | 187 case Channel::MODE_CLIENT: |
| 188 return make_scoped_ptr( | 188 return make_scoped_ptr( |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 233 &ChannelMojo::InitDelegate, base::Unretained(this), delegate)); | 233 &ChannelMojo::InitDelegate, base::Unretained(this), delegate)); |
| 234 } | 234 } |
| 235 } | 235 } |
| 236 } | 236 } |
| 237 | 237 |
| 238 ChannelMojo::~ChannelMojo() { | 238 ChannelMojo::~ChannelMojo() { |
| 239 Close(); | 239 Close(); |
| 240 } | 240 } |
| 241 | 241 |
| 242 void ChannelMojo::InitDelegate(ChannelMojo::Delegate* delegate) { | 242 void ChannelMojo::InitDelegate(ChannelMojo::Delegate* delegate) { |
| 243 delegate->OnChannelCreated(weak_factory_.GetWeakPtr()); | |
| 244 base::AutoLock l(lock_); | |
| 243 delegate_ = delegate->ToWeakPtr(); | 245 delegate_ = delegate->ToWeakPtr(); |
| 244 delegate_->OnChannelCreated(weak_factory_.GetWeakPtr()); | |
| 245 } | 246 } |
| 246 | 247 |
| 247 mojo::ScopedMessagePipeHandle ChannelMojo::CreateMessagingPipe( | 248 mojo::ScopedMessagePipeHandle ChannelMojo::CreateMessagingPipe( |
| 248 mojo::embedder::ScopedPlatformHandle handle) { | 249 mojo::embedder::ScopedPlatformHandle handle) { |
| 249 DCHECK(!channel_info_.get()); | 250 DCHECK(!channel_info_.get()); |
| 250 mojo::embedder::ChannelInfo* channel_info; | 251 mojo::embedder::ChannelInfo* channel_info; |
| 251 mojo::ScopedMessagePipeHandle pipe = | 252 mojo::ScopedMessagePipeHandle pipe = |
| 252 mojo::embedder::CreateChannelOnIOThread(handle.Pass(), &channel_info); | 253 mojo::embedder::CreateChannelOnIOThread(handle.Pass(), &channel_info); |
| 253 channel_info_.reset(channel_info); | 254 channel_info_.reset(channel_info); |
| 254 return pipe.Pass(); | 255 return pipe.Pass(); |
| 255 } | 256 } |
| 256 | 257 |
| 257 bool ChannelMojo::Connect() { | 258 bool ChannelMojo::Connect() { |
| 258 DCHECK(!message_reader_); | 259 DCHECK(!message_reader_); |
| 259 return bootstrap_->Connect(); | 260 return bootstrap_->Connect(); |
| 260 } | 261 } |
| 261 | 262 |
| 262 void ChannelMojo::Close() { | 263 void ChannelMojo::Close() { |
| 263 message_reader_.reset(); | 264 // |message_reader_| has to be cleared inside the lock, |
| 265 // but the instance has to be deleted outside. | |
| 266 scoped_ptr<internal::MessagePipeReader, ReaderDeleter> to_be_dead; | |
| 267 | |
| 268 base::AutoLock l(lock_); | |
| 269 to_be_dead = message_reader_.Pass(); | |
| 264 channel_info_.reset(); | 270 channel_info_.reset(); |
| 265 } | 271 } |
| 266 | 272 |
| 267 void ChannelMojo::OnBootstrapError() { | 273 void ChannelMojo::OnBootstrapError() { |
| 268 listener_->OnChannelError(); | 274 listener_->OnChannelError(); |
| 269 } | 275 } |
| 270 | 276 |
| 271 void ChannelMojo::InitMessageReader(mojo::ScopedMessagePipeHandle pipe, | 277 void ChannelMojo::InitMessageReader(mojo::ScopedMessagePipeHandle pipe, |
| 272 int32_t peer_pid) { | 278 int32_t peer_pid) { |
| 273 message_reader_ = | 279 scoped_ptr<internal::MessagePipeReader> reader = |
| 274 make_scoped_ptr(new internal::MessagePipeReader(pipe.Pass(), this)); | 280 make_scoped_ptr(new internal::MessagePipeReader(pipe.Pass(), this)); |
| 281 MojoResult send_result = MOJO_RESULT_OK; | |
| 275 | 282 |
| 276 for (size_t i = 0; i < pending_messages_.size(); ++i) { | 283 { |
| 277 bool sent = message_reader_->Send(make_scoped_ptr(pending_messages_[i])); | 284 base::AutoLock l(lock_); |
| 278 pending_messages_[i] = NULL; | 285 ScopedVector<Message> pending; |
| 279 if (!sent) { | 286 |
| 280 pending_messages_.clear(); | 287 pending_messages_.swap(pending); |
| 281 listener_->OnChannelError(); | 288 for (size_t i = 0; i < pending.size(); ++i) { |
| 282 return; | 289 send_result = reader->Send(make_scoped_ptr(pending[i])); |
| 290 pending[i] = nullptr; | |
| 291 if (send_result != MOJO_RESULT_OK) | |
| 292 break; | |
| 283 } | 293 } |
| 294 | |
| 295 // We set |message_reader_| here and won't get any |pending_messages_| | |
| 296 // hereafter. Although we might have some if there is an error, we don't | |
| 297 // care. They cannot be sent anyway. | |
| 298 if (send_result == MOJO_RESULT_OK) | |
| 299 message_reader_ = reader.Pass(); | |
| 284 } | 300 } |
| 285 | 301 |
| 286 pending_messages_.clear(); | 302 // This should be done outside the |lock_| as delegates are called through |
| 303 // |CloseWithError()|. | |
| 304 if (reader.get()) { | |
| 305 DCHECK(!message_reader_.get()); | |
| 306 reader->CloseWithError(send_result); | |
| 307 return; | |
| 308 } | |
| 287 | 309 |
| 310 DCHECK(message_reader_.get()); | |
| 288 set_peer_pid(peer_pid); | 311 set_peer_pid(peer_pid); |
| 289 listener_->OnChannelConnected(static_cast<int32_t>(GetPeerPID())); | 312 listener_->OnChannelConnected(static_cast<int32_t>(GetPeerPID())); |
| 290 } | 313 } |
| 291 | 314 |
| 292 void ChannelMojo::OnPipeClosed(internal::MessagePipeReader* reader) { | 315 void ChannelMojo::OnPipeClosed(internal::MessagePipeReader* reader) { |
| 293 Close(); | 316 Close(); |
| 294 } | 317 } |
| 295 | 318 |
| 296 void ChannelMojo::OnPipeError(internal::MessagePipeReader* reader) { | 319 void ChannelMojo::OnPipeError(internal::MessagePipeReader* reader) { |
| 297 listener_->OnChannelError(); | 320 listener_->OnChannelError(); |
| 298 } | 321 } |
| 299 | 322 |
| 323 base::TaskRunner* ChannelMojo::GetIOTaskRunner() { | |
| 324 base::AutoLock l(lock_); | |
| 325 if (!delegate_) | |
| 326 return nullptr; | |
| 327 return delegate_->GetIOTaskRunner().get(); | |
| 328 } | |
| 300 | 329 |
| 330 // Reminder: Be thread-safe. | |
| 301 bool ChannelMojo::Send(Message* message) { | 331 bool ChannelMojo::Send(Message* message) { |
| 302 if (!message_reader_) { | 332 MojoResult send_result = MOJO_RESULT_OK; |
| 303 pending_messages_.push_back(message); | 333 |
| 304 return true; | 334 { |
| 335 base::AutoLock l(lock_); | |
| 336 | |
| 337 if (!message_reader_) { | |
| 338 pending_messages_.push_back(message); | |
| 339 return true; | |
| 340 } | |
| 341 | |
| 342 send_result = message_reader_->Send(make_scoped_ptr(message)); | |
| 305 } | 343 } |
| 306 | 344 |
| 307 return message_reader_->Send(make_scoped_ptr(message)); | 345 if (send_result != MOJO_RESULT_OK) { |
| 346 if (base::TaskRunner* runner = GetIOTaskRunner()) { | |
| 347 runner->PostTask( | |
| 348 FROM_HERE, | |
| 349 base::Bind(&internal::MessagePipeReader::CloseWithError, | |
| 350 base::Unretained(message_reader_.get()), send_result)); | |
| 351 // The error shouln't be visible at this point. | |
| 352 // It will be known eventually by |CloseWithError()| on IO thread. | |
| 353 return true; | |
| 354 } | |
| 355 | |
| 356 message_reader_->CloseWithError(send_result); | |
| 357 return false; | |
| 358 } | |
| 359 | |
| 360 return true; | |
| 361 } | |
| 362 | |
| 363 bool ChannelMojo::IsSendThreadSafe() const { | |
| 364 return true; | |
| 308 } | 365 } |
| 309 | 366 |
| 310 base::ProcessId ChannelMojo::GetPeerPID() const { | 367 base::ProcessId ChannelMojo::GetPeerPID() const { |
| 311 return peer_pid_; | 368 return peer_pid_; |
| 312 } | 369 } |
| 313 | 370 |
| 314 base::ProcessId ChannelMojo::GetSelfPID() const { | 371 base::ProcessId ChannelMojo::GetSelfPID() const { |
| 315 return base::GetCurrentProcId(); | 372 return base::GetCurrentProcId(); |
| 316 } | 373 } |
| 317 | 374 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 392 | 449 |
| 393 fdset->CommitAll(); | 450 fdset->CommitAll(); |
| 394 } | 451 } |
| 395 | 452 |
| 396 return MOJO_RESULT_OK; | 453 return MOJO_RESULT_OK; |
| 397 } | 454 } |
| 398 | 455 |
| 399 #endif // defined(OS_POSIX) && !defined(OS_NACL) | 456 #endif // defined(OS_POSIX) && !defined(OS_NACL) |
| 400 | 457 |
| 401 } // namespace IPC | 458 } // namespace IPC |
| OLD | NEW |