| 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 |