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/ipc_mojo_bootstrap.h" | 5 #include "ipc/ipc_mojo_bootstrap.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <map> | 9 #include <map> |
10 #include <memory> | 10 #include <memory> |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 | 154 |
155 base::AutoLock locker(lock_); | 155 base::AutoLock locker(lock_); |
156 bool inserted = false; | 156 bool inserted = false; |
157 Endpoint* endpoint = FindOrInsertEndpoint(id, &inserted); | 157 Endpoint* endpoint = FindOrInsertEndpoint(id, &inserted); |
158 if (inserted && encountered_error_) | 158 if (inserted && encountered_error_) |
159 endpoint->set_peer_closed(); | 159 endpoint->set_peer_closed(); |
160 | 160 |
161 return CreateScopedInterfaceEndpointHandle(id, true); | 161 return CreateScopedInterfaceEndpointHandle(id, true); |
162 } | 162 } |
163 | 163 |
164 void CloseEndpointHandle(mojo::InterfaceId id, bool is_local) override { | 164 void CloseEndpointHandle( |
| 165 mojo::InterfaceId id, |
| 166 bool is_local, |
| 167 const base::Optional<mojo::DisconnectReason>& reason) override { |
165 if (!mojo::IsValidInterfaceId(id)) | 168 if (!mojo::IsValidInterfaceId(id)) |
166 return; | 169 return; |
167 | 170 |
168 base::AutoLock locker(lock_); | 171 base::AutoLock locker(lock_); |
169 if (!is_local) { | 172 if (!is_local) { |
170 DCHECK(ContainsKey(endpoints_, id)); | 173 DCHECK(ContainsKey(endpoints_, id)); |
171 DCHECK(!mojo::IsMasterInterfaceId(id)); | 174 DCHECK(!mojo::IsMasterInterfaceId(id)); |
172 | 175 |
173 base::AutoUnlock unlocker(lock_); | 176 base::AutoUnlock unlocker(lock_); |
174 control_message_proxy_.NotifyEndpointClosedBeforeSent(id); | 177 control_message_proxy_.NotifyEndpointClosedBeforeSent(id); |
175 return; | 178 return; |
176 } | 179 } |
177 | 180 |
178 DCHECK(ContainsKey(endpoints_, id)); | 181 DCHECK(ContainsKey(endpoints_, id)); |
179 Endpoint* endpoint = endpoints_[id].get(); | 182 Endpoint* endpoint = endpoints_[id].get(); |
180 DCHECK(!endpoint->client()); | 183 DCHECK(!endpoint->client()); |
181 DCHECK(!endpoint->closed()); | 184 DCHECK(!endpoint->closed()); |
182 MarkClosedAndMaybeRemove(endpoint); | 185 MarkClosedAndMaybeRemove(endpoint); |
183 | 186 |
184 base::AutoUnlock unlocker(lock_); | 187 base::AutoUnlock unlocker(lock_); |
185 if (!mojo::IsMasterInterfaceId(id)) | 188 if (!mojo::IsMasterInterfaceId(id) || reason) |
186 control_message_proxy_.NotifyPeerEndpointClosed(id); | 189 control_message_proxy_.NotifyPeerEndpointClosed(id, reason); |
187 } | 190 } |
188 | 191 |
189 mojo::InterfaceEndpointController* AttachEndpointClient( | 192 mojo::InterfaceEndpointController* AttachEndpointClient( |
190 const mojo::ScopedInterfaceEndpointHandle& handle, | 193 const mojo::ScopedInterfaceEndpointHandle& handle, |
191 mojo::InterfaceEndpointClient* client, | 194 mojo::InterfaceEndpointClient* client, |
192 scoped_refptr<base::SingleThreadTaskRunner> runner) override { | 195 scoped_refptr<base::SingleThreadTaskRunner> runner) override { |
193 const mojo::InterfaceId id = handle.id(); | 196 const mojo::InterfaceId id = handle.id(); |
194 | 197 |
195 DCHECK(mojo::IsValidInterfaceId(id)); | 198 DCHECK(mojo::IsValidInterfaceId(id)); |
196 DCHECK(client); | 199 DCHECK(client); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 bool peer_closed() const { | 260 bool peer_closed() const { |
258 controller_->lock_.AssertAcquired(); | 261 controller_->lock_.AssertAcquired(); |
259 return peer_closed_; | 262 return peer_closed_; |
260 } | 263 } |
261 | 264 |
262 void set_peer_closed() { | 265 void set_peer_closed() { |
263 controller_->lock_.AssertAcquired(); | 266 controller_->lock_.AssertAcquired(); |
264 peer_closed_ = true; | 267 peer_closed_ = true; |
265 } | 268 } |
266 | 269 |
| 270 const base::Optional<mojo::DisconnectReason>& disconnect_reason() const { |
| 271 return disconnect_reason_; |
| 272 } |
| 273 |
| 274 void set_disconnect_reason( |
| 275 const base::Optional<mojo::DisconnectReason>& disconnect_reason) { |
| 276 disconnect_reason_ = disconnect_reason; |
| 277 } |
| 278 |
267 base::SingleThreadTaskRunner* task_runner() const { | 279 base::SingleThreadTaskRunner* task_runner() const { |
268 return task_runner_.get(); | 280 return task_runner_.get(); |
269 } | 281 } |
270 | 282 |
271 mojo::InterfaceEndpointClient* client() const { | 283 mojo::InterfaceEndpointClient* client() const { |
272 controller_->lock_.AssertAcquired(); | 284 controller_->lock_.AssertAcquired(); |
273 return client_; | 285 return client_; |
274 } | 286 } |
275 | 287 |
276 void AttachClient(mojo::InterfaceEndpointClient* client, | 288 void AttachClient(mojo::InterfaceEndpointClient* client, |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 uint32_t id = next_sync_message_id_++; | 441 uint32_t id = next_sync_message_id_++; |
430 DCHECK(sync_messages_.empty() || sync_messages_.front().first != id); | 442 DCHECK(sync_messages_.empty() || sync_messages_.front().first != id); |
431 return id; | 443 return id; |
432 } | 444 } |
433 | 445 |
434 ChannelAssociatedGroupController* const controller_; | 446 ChannelAssociatedGroupController* const controller_; |
435 const mojo::InterfaceId id_; | 447 const mojo::InterfaceId id_; |
436 | 448 |
437 bool closed_ = false; | 449 bool closed_ = false; |
438 bool peer_closed_ = false; | 450 bool peer_closed_ = false; |
| 451 base::Optional<mojo::DisconnectReason> disconnect_reason_; |
439 mojo::InterfaceEndpointClient* client_ = nullptr; | 452 mojo::InterfaceEndpointClient* client_ = nullptr; |
440 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 453 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
441 std::unique_ptr<mojo::SyncHandleWatcher> sync_watcher_; | 454 std::unique_ptr<mojo::SyncHandleWatcher> sync_watcher_; |
442 std::unique_ptr<MojoEvent> sync_message_event_; | 455 std::unique_ptr<MojoEvent> sync_message_event_; |
443 std::queue<std::pair<uint32_t, mojo::Message>> sync_messages_; | 456 std::queue<std::pair<uint32_t, mojo::Message>> sync_messages_; |
444 uint32_t next_sync_message_id_ = 0; | 457 uint32_t next_sync_message_id_ = 0; |
445 | 458 |
446 DISALLOW_COPY_AND_ASSIGN(Endpoint); | 459 DISALLOW_COPY_AND_ASSIGN(Endpoint); |
447 }; | 460 }; |
448 | 461 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 if (endpoint->client()) | 544 if (endpoint->client()) |
532 NotifyEndpointOfError(endpoint.get(), false /* force_async */); | 545 NotifyEndpointOfError(endpoint.get(), false /* force_async */); |
533 } | 546 } |
534 } | 547 } |
535 | 548 |
536 void NotifyEndpointOfError(Endpoint* endpoint, bool force_async) { | 549 void NotifyEndpointOfError(Endpoint* endpoint, bool force_async) { |
537 lock_.AssertAcquired(); | 550 lock_.AssertAcquired(); |
538 DCHECK(endpoint->task_runner() && endpoint->client()); | 551 DCHECK(endpoint->task_runner() && endpoint->client()); |
539 if (endpoint->task_runner()->BelongsToCurrentThread() && !force_async) { | 552 if (endpoint->task_runner()->BelongsToCurrentThread() && !force_async) { |
540 mojo::InterfaceEndpointClient* client = endpoint->client(); | 553 mojo::InterfaceEndpointClient* client = endpoint->client(); |
| 554 base::Optional<mojo::DisconnectReason> reason( |
| 555 endpoint->disconnect_reason()); |
541 | 556 |
542 base::AutoUnlock unlocker(lock_); | 557 base::AutoUnlock unlocker(lock_); |
543 client->NotifyError(); | 558 client->NotifyError(reason); |
544 } else { | 559 } else { |
545 endpoint->task_runner()->PostTask( | 560 endpoint->task_runner()->PostTask( |
546 FROM_HERE, | 561 FROM_HERE, |
547 base::Bind(&ChannelAssociatedGroupController | 562 base::Bind(&ChannelAssociatedGroupController |
548 ::NotifyEndpointOfErrorOnEndpointThread, this, endpoint->id(), | 563 ::NotifyEndpointOfErrorOnEndpointThread, this, endpoint->id(), |
549 endpoint)); | 564 endpoint)); |
550 } | 565 } |
551 } | 566 } |
552 | 567 |
553 void NotifyEndpointOfErrorOnEndpointThread(mojo::InterfaceId id, | 568 void NotifyEndpointOfErrorOnEndpointThread(mojo::InterfaceId id, |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
714 return iter->second.get(); | 729 return iter->second.get(); |
715 if (!create) | 730 if (!create) |
716 return nullptr; | 731 return nullptr; |
717 bool inserted = false; | 732 bool inserted = false; |
718 Endpoint* endpoint = FindOrInsertEndpoint(id, &inserted); | 733 Endpoint* endpoint = FindOrInsertEndpoint(id, &inserted); |
719 DCHECK(inserted); | 734 DCHECK(inserted); |
720 return endpoint; | 735 return endpoint; |
721 } | 736 } |
722 | 737 |
723 // mojo::PipeControlMessageHandlerDelegate: | 738 // mojo::PipeControlMessageHandlerDelegate: |
724 bool OnPeerAssociatedEndpointClosed(mojo::InterfaceId id) override { | 739 bool OnPeerAssociatedEndpointClosed( |
| 740 mojo::InterfaceId id, |
| 741 const base::Optional<mojo::DisconnectReason>& reason) override { |
725 DCHECK(thread_checker_.CalledOnValidThread()); | 742 DCHECK(thread_checker_.CalledOnValidThread()); |
726 | 743 |
727 if (mojo::IsMasterInterfaceId(id)) | 744 DCHECK(!mojo::IsMasterInterfaceId(id) || reason); |
728 return false; | |
729 | 745 |
730 scoped_refptr<ChannelAssociatedGroupController> keepalive(this); | 746 scoped_refptr<ChannelAssociatedGroupController> keepalive(this); |
731 base::AutoLock locker(lock_); | 747 base::AutoLock locker(lock_); |
732 scoped_refptr<Endpoint> endpoint = FindOrInsertEndpoint(id, nullptr); | 748 scoped_refptr<Endpoint> endpoint = FindOrInsertEndpoint(id, nullptr); |
| 749 if (reason) |
| 750 endpoint->set_disconnect_reason(reason); |
733 if (!endpoint->peer_closed()) { | 751 if (!endpoint->peer_closed()) { |
734 if (endpoint->client()) | 752 if (endpoint->client()) |
735 NotifyEndpointOfError(endpoint.get(), false /* force_async */); | 753 NotifyEndpointOfError(endpoint.get(), false /* force_async */); |
736 MarkPeerClosedAndMaybeRemove(endpoint.get()); | 754 MarkPeerClosedAndMaybeRemove(endpoint.get()); |
737 } | 755 } |
738 | 756 |
739 return true; | 757 return true; |
740 } | 758 } |
741 | 759 |
742 bool OnAssociatedEndpointClosedBeforeSent(mojo::InterfaceId id) override { | 760 bool OnAssociatedEndpointClosedBeforeSent(mojo::InterfaceId id) override { |
743 DCHECK(thread_checker_.CalledOnValidThread()); | 761 DCHECK(thread_checker_.CalledOnValidThread()); |
744 | 762 |
745 if (mojo::IsMasterInterfaceId(id)) | 763 if (mojo::IsMasterInterfaceId(id)) |
746 return false; | 764 return false; |
747 | 765 |
748 { | 766 { |
749 base::AutoLock locker(lock_); | 767 base::AutoLock locker(lock_); |
750 Endpoint* endpoint = FindOrInsertEndpoint(id, nullptr); | 768 Endpoint* endpoint = FindOrInsertEndpoint(id, nullptr); |
751 DCHECK(!endpoint->closed()); | 769 DCHECK(!endpoint->closed()); |
752 MarkClosedAndMaybeRemove(endpoint); | 770 MarkClosedAndMaybeRemove(endpoint); |
753 } | 771 } |
754 | 772 |
755 control_message_proxy_.NotifyPeerEndpointClosed(id); | 773 control_message_proxy_.NotifyPeerEndpointClosed(id, base::nullopt); |
756 return true; | 774 return true; |
757 } | 775 } |
758 | 776 |
759 // Checked in places which must be run on the master endpoint's thread. | 777 // Checked in places which must be run on the master endpoint's thread. |
760 base::ThreadChecker thread_checker_; | 778 base::ThreadChecker thread_checker_; |
761 | 779 |
762 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 780 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
763 | 781 |
764 scoped_refptr<base::SingleThreadTaskRunner> proxy_task_runner_; | 782 scoped_refptr<base::SingleThreadTaskRunner> proxy_task_runner_; |
765 const bool set_interface_id_namespace_bit_; | 783 const bool set_interface_id_namespace_bit_; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
850 Channel::Mode mode, | 868 Channel::Mode mode, |
851 Delegate* delegate, | 869 Delegate* delegate, |
852 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) { | 870 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) { |
853 return base::MakeUnique<MojoBootstrapImpl>( | 871 return base::MakeUnique<MojoBootstrapImpl>( |
854 std::move(handle), delegate, | 872 std::move(handle), delegate, |
855 new ChannelAssociatedGroupController(mode == Channel::MODE_SERVER, | 873 new ChannelAssociatedGroupController(mode == Channel::MODE_SERVER, |
856 ipc_task_runner)); | 874 ipc_task_runner)); |
857 } | 875 } |
858 | 876 |
859 } // namespace IPC | 877 } // namespace IPC |
OLD | NEW |