OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "mojo/edk/system/data_pipe_consumer_dispatcher.h" | 5 #include "mojo/edk/system/data_pipe_consumer_dispatcher.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 13 matching lines...) Expand all Loading... |
24 | 24 |
25 void DataPipeConsumerDispatcher::Init( | 25 void DataPipeConsumerDispatcher::Init( |
26 ScopedPlatformHandle message_pipe, | 26 ScopedPlatformHandle message_pipe, |
27 char* serialized_read_buffer, size_t serialized_read_buffer_size) { | 27 char* serialized_read_buffer, size_t serialized_read_buffer_size) { |
28 if (message_pipe.is_valid()) { | 28 if (message_pipe.is_valid()) { |
29 channel_ = RawChannel::Create(message_pipe.Pass()); | 29 channel_ = RawChannel::Create(message_pipe.Pass()); |
30 channel_->SetSerializedData( | 30 channel_->SetSerializedData( |
31 serialized_read_buffer, serialized_read_buffer_size, nullptr, 0u); | 31 serialized_read_buffer, serialized_read_buffer_size, nullptr, 0u); |
32 internal::g_io_thread_task_runner->PostTask( | 32 internal::g_io_thread_task_runner->PostTask( |
33 FROM_HERE, base::Bind(&DataPipeConsumerDispatcher::InitOnIO, this)); | 33 FROM_HERE, base::Bind(&DataPipeConsumerDispatcher::InitOnIO, this)); |
| 34 } else { |
| 35 // The data pipe consumer could have read all the data and the producer |
| 36 // closed its end subsequently (before the consumer was sent). In that case |
| 37 // when we deserialize the consumer we must make sure to set error_ or |
| 38 // otherwise the peer-closed signal will never be satisfied. |
| 39 error_ = true; |
34 } | 40 } |
35 } | 41 } |
36 | 42 |
37 void DataPipeConsumerDispatcher::InitOnIO() { | 43 void DataPipeConsumerDispatcher::InitOnIO() { |
38 base::AutoLock locker(lock()); | 44 base::AutoLock locker(lock()); |
39 calling_init_ = true; | 45 calling_init_ = true; |
40 if (channel_) | 46 if (channel_) |
41 channel_->Init(this); | 47 channel_->Init(this); |
42 calling_init_ = false; | 48 calling_init_ = false; |
43 } | 49 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 buffer += header->data_size; | 91 buffer += header->data_size; |
86 } | 92 } |
87 | 93 |
88 if (header->read_buffer_size) { | 94 if (header->read_buffer_size) { |
89 serialized_read_buffer = buffer; | 95 serialized_read_buffer = buffer; |
90 serialized_read_buffer_size = header->read_buffer_size; | 96 serialized_read_buffer_size = header->read_buffer_size; |
91 buffer += header->read_buffer_size; | 97 buffer += header->read_buffer_size; |
92 } | 98 } |
93 } | 99 } |
94 | 100 |
95 if (platform_handle.is_valid()) { | 101 rv->Init(platform_handle.Pass(), serialized_read_buffer, |
96 rv->Init(platform_handle.Pass(), serialized_read_buffer, | 102 serialized_read_buffer_size); |
97 serialized_read_buffer_size); | |
98 } else { | |
99 // The data pipe consumer could have read all the data and the producer | |
100 // closed its end subsequently (before the consumer was sent). In that case | |
101 // when we deserialize the consumer we must make sure to set error_ or | |
102 // otherwise the peer-closed signal will never be satisfied. | |
103 rv->error_ = true; | |
104 } | |
105 return rv; | 103 return rv; |
106 } | 104 } |
107 | 105 |
108 DataPipeConsumerDispatcher::DataPipeConsumerDispatcher( | 106 DataPipeConsumerDispatcher::DataPipeConsumerDispatcher( |
109 const MojoCreateDataPipeOptions& options) | 107 const MojoCreateDataPipeOptions& options) |
110 : options_(options), | 108 : options_(options), |
111 channel_(nullptr), | 109 channel_(nullptr), |
112 calling_init_(false), | 110 calling_init_(false), |
113 in_two_phase_read_(false), | 111 in_two_phase_read_(false), |
114 two_phase_max_bytes_read_(0), | 112 two_phase_max_bytes_read_(0), |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
446 LOG(ERROR) << "DataPipeConsumerDispatcher read error (unknown)"; | 444 LOG(ERROR) << "DataPipeConsumerDispatcher read error (unknown)"; |
447 break; | 445 break; |
448 case ERROR_WRITE: | 446 case ERROR_WRITE: |
449 LOG(ERROR) << "DataPipeConsumerDispatcher shouldn't write messages"; | 447 LOG(ERROR) << "DataPipeConsumerDispatcher shouldn't write messages"; |
450 break; | 448 break; |
451 } | 449 } |
452 | 450 |
453 error_ = true; | 451 error_ = true; |
454 if (started_transport_.Try()) { | 452 if (started_transport_.Try()) { |
455 base::AutoLock locker(lock()); | 453 base::AutoLock locker(lock()); |
| 454 // We can get two OnError callbacks before the post task below completes. |
| 455 // Although RawChannel still has a pointer to this object until Shutdown is |
| 456 // called, that is safe since this class always does a PostTask to the IO |
| 457 // thread to self destruct. |
| 458 if (!channel_) |
| 459 return; |
| 460 |
456 awakable_list_.AwakeForStateChange(GetHandleSignalsStateImplNoLock()); | 461 awakable_list_.AwakeForStateChange(GetHandleSignalsStateImplNoLock()); |
457 started_transport_.Release(); | 462 started_transport_.Release(); |
458 | 463 |
459 base::MessageLoop::current()->PostTask( | 464 base::MessageLoop::current()->PostTask( |
460 FROM_HERE, | 465 FROM_HERE, |
461 base::Bind(&RawChannel::Shutdown, base::Unretained(channel_))); | 466 base::Bind(&RawChannel::Shutdown, base::Unretained(channel_))); |
462 channel_ = nullptr; | 467 channel_ = nullptr; |
463 } else { | 468 } else { |
464 // We must be waiting to call ReleaseHandle. It will call Shutdown. | 469 // We must be waiting to call ReleaseHandle. It will call Shutdown. |
465 } | 470 } |
(...skipping 11 matching lines...) Expand all Loading... |
477 CHECK(serialized_write_buffer.empty()); | 482 CHECK(serialized_write_buffer.empty()); |
478 | 483 |
479 channel_ = nullptr; | 484 channel_ = nullptr; |
480 } | 485 } |
481 | 486 |
482 serialized_ = true; | 487 serialized_ = true; |
483 } | 488 } |
484 | 489 |
485 } // namespace edk | 490 } // namespace edk |
486 } // namespace mojo | 491 } // namespace mojo |
OLD | NEW |