| OLD | NEW |
| (Empty) |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "mojo/edk/system/broker_host.h" | |
| 6 | |
| 7 #include <fcntl.h> | |
| 8 #include <unistd.h> | |
| 9 | |
| 10 #include <utility> | |
| 11 | |
| 12 #include "base/logging.h" | |
| 13 #include "base/memory/ref_counted.h" | |
| 14 #include "base/message_loop/message_loop.h" | |
| 15 #include "base/threading/thread_task_runner_handle.h" | |
| 16 #include "mojo/edk/embedder/embedder_internal.h" | |
| 17 #include "mojo/edk/embedder/platform_channel_utils_posix.h" | |
| 18 #include "mojo/edk/embedder/platform_handle_vector.h" | |
| 19 #include "mojo/edk/embedder/platform_shared_buffer.h" | |
| 20 #include "mojo/edk/system/broker_messages.h" | |
| 21 | |
| 22 namespace mojo { | |
| 23 namespace edk { | |
| 24 | |
| 25 namespace { | |
| 26 // To prevent abuse, limit the maximum size of shared memory buffers. | |
| 27 // TODO(amistry): Re-consider this limit, or do something smarter. | |
| 28 const size_t kMaxSharedBufferSize = 16 * 1024 * 1024; | |
| 29 } | |
| 30 | |
| 31 BrokerHost::BrokerHost(ScopedPlatformHandle platform_handle) { | |
| 32 CHECK(platform_handle.is_valid()); | |
| 33 | |
| 34 base::MessageLoop::current()->AddDestructionObserver(this); | |
| 35 | |
| 36 channel_ = Channel::Create(this, std::move(platform_handle), | |
| 37 base::ThreadTaskRunnerHandle::Get()); | |
| 38 channel_->Start(); | |
| 39 } | |
| 40 | |
| 41 BrokerHost::~BrokerHost() { | |
| 42 // We're always destroyed on the creation thread, which is the IO thread. | |
| 43 base::MessageLoop::current()->RemoveDestructionObserver(this); | |
| 44 | |
| 45 if (channel_) | |
| 46 channel_->ShutDown(); | |
| 47 } | |
| 48 | |
| 49 void BrokerHost::SendChannel(ScopedPlatformHandle handle) { | |
| 50 CHECK(handle.is_valid()); | |
| 51 CHECK(channel_); | |
| 52 | |
| 53 Channel::MessagePtr message = | |
| 54 CreateBrokerMessage(BrokerMessageType::INIT, 1, nullptr); | |
| 55 ScopedPlatformHandleVectorPtr handles; | |
| 56 handles.reset(new PlatformHandleVector(1)); | |
| 57 handles->at(0) = handle.release(); | |
| 58 message->SetHandles(std::move(handles)); | |
| 59 | |
| 60 channel_->Write(std::move(message)); | |
| 61 } | |
| 62 | |
| 63 void BrokerHost::OnBufferRequest(size_t num_bytes) { | |
| 64 scoped_refptr<PlatformSharedBuffer> buffer; | |
| 65 scoped_refptr<PlatformSharedBuffer> read_only_buffer; | |
| 66 if (num_bytes <= kMaxSharedBufferSize) { | |
| 67 buffer = PlatformSharedBuffer::Create(num_bytes); | |
| 68 if (buffer) | |
| 69 read_only_buffer = buffer->CreateReadOnlyDuplicate(); | |
| 70 if (!read_only_buffer) | |
| 71 buffer = nullptr; | |
| 72 } else { | |
| 73 LOG(ERROR) << "Shared buffer request too large: " << num_bytes; | |
| 74 } | |
| 75 | |
| 76 Channel::MessagePtr message = CreateBrokerMessage( | |
| 77 BrokerMessageType::BUFFER_RESPONSE, buffer ? 2 : 0, nullptr); | |
| 78 if (buffer) { | |
| 79 ScopedPlatformHandleVectorPtr handles; | |
| 80 handles.reset(new PlatformHandleVector(2)); | |
| 81 handles->at(0) = buffer->PassPlatformHandle().release(); | |
| 82 handles->at(1) = read_only_buffer->PassPlatformHandle().release(); | |
| 83 message->SetHandles(std::move(handles)); | |
| 84 } | |
| 85 | |
| 86 channel_->Write(std::move(message)); | |
| 87 } | |
| 88 | |
| 89 void BrokerHost::OnChannelMessage(const void* payload, | |
| 90 size_t payload_size, | |
| 91 ScopedPlatformHandleVectorPtr handles) { | |
| 92 if (payload_size < sizeof(BrokerMessageHeader)) | |
| 93 return; | |
| 94 | |
| 95 const BrokerMessageHeader* header = | |
| 96 static_cast<const BrokerMessageHeader*>(payload); | |
| 97 switch (header->type) { | |
| 98 case BrokerMessageType::BUFFER_REQUEST: | |
| 99 if (payload_size == | |
| 100 sizeof(BrokerMessageHeader) + sizeof(BufferRequestData)) { | |
| 101 const BufferRequestData* request = | |
| 102 reinterpret_cast<const BufferRequestData*>(header + 1); | |
| 103 OnBufferRequest(request->size); | |
| 104 return; | |
| 105 } | |
| 106 break; | |
| 107 | |
| 108 default: | |
| 109 break; | |
| 110 } | |
| 111 | |
| 112 LOG(ERROR) << "Unexpected broker message type: " << header->type; | |
| 113 } | |
| 114 | |
| 115 void BrokerHost::OnChannelError() { | |
| 116 if (channel_) { | |
| 117 channel_->ShutDown(); | |
| 118 channel_ = nullptr; | |
| 119 } | |
| 120 | |
| 121 delete this; | |
| 122 } | |
| 123 | |
| 124 void BrokerHost::WillDestroyCurrentMessageLoop() { | |
| 125 delete this; | |
| 126 } | |
| 127 | |
| 128 } // namespace edk | |
| 129 } // namespace mojo | |
| OLD | NEW |