15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "mojo/embedder/embedder.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/bind.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/location.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/logging.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 1103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "mojo/embedder/platform_support.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "mojo/system/channel.h" 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "mojo/system/channel_endpoint.h" 14a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "mojo/system/core.h" 15a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "mojo/system/entrypoints.h" 16010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "mojo/system/message_in_transit.h" 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "mojo/system/message_pipe_dispatcher.h" 18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "mojo/system/platform_handle_dispatcher.h" 19c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "mojo/system/raw_channel.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace mojo { 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace embedder { 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 24010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// This is defined here (instead of a header file), since it's opaque to the 25010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// outside world. But we need to define it before our (internal-only) functions 26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// that use it. 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct ChannelInfo { 286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ChannelInfo() {} 29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ~ChannelInfo() {} 30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<system::Channel> channel; 326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // May be null, in which case |DestroyChannelOnIOThread()| must be used (from 346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // the IO thread), instead of |DestroyChannel()|. 356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_refptr<base::TaskRunner> io_thread_task_runner; 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace { 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Helper for |CreateChannel...()|. (Note: May return null for some failures.) 41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)scoped_refptr<system::Channel> MakeChannel( 4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) system::Core* core, 43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ScopedPlatformHandle platform_handle, 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<system::ChannelEndpoint> channel_endpoint) { 45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(platform_handle.is_valid()); 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Create and initialize a |system::Channel|. 4803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_refptr<system::Channel> channel = 4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) new system::Channel(core->platform_support()); 50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!channel->Init(system::RawChannel::Create(platform_handle.Pass()))) { 51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // This is very unusual (e.g., maybe |platform_handle| was invalid or we 52010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // reached some system resource limit). 53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) LOG(ERROR) << "Channel::Init() failed"; 54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Return null, since |Shutdown()| shouldn't be called in this case. 55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return scoped_refptr<system::Channel>(); 56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Once |Init()| has succeeded, we have to return |channel| (since 58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // |Shutdown()| will have to be called on it). 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Attach the endpoint. 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) system::MessageInTransit::EndpointId endpoint_id = 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci channel->AttachEndpoint(channel_endpoint); 63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (endpoint_id == system::MessageInTransit::kInvalidEndpointId) { 64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // This means that, e.g., the other endpoint of the message pipe was closed 65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // first. But it's not necessarily an error per se. 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(2) << "Channel::AttachEndpoint() failed"; 67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return channel; 68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 69010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CHECK_EQ(endpoint_id, system::Channel::kBootstrapEndpointId); 70010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 71010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!channel->RunMessagePipeEndpoint(system::Channel::kBootstrapEndpointId, 72010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) system::Channel::kBootstrapEndpointId)) { 73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Currently, there's no reason for this to fail. 74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) NOTREACHED() << "Channel::RunMessagePipeEndpoint() failed"; 75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return channel; 76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return channel; 79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void CreateChannelHelper( 8203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) system::Core* core, 83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ScopedPlatformHandle platform_handle, 846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_ptr<ChannelInfo> channel_info, 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<system::ChannelEndpoint> channel_endpoint, 86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DidCreateChannelCallback callback, 87010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_refptr<base::TaskRunner> callback_thread_task_runner) { 8803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) channel_info->channel = 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MakeChannel(core, platform_handle.Pass(), channel_endpoint); 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Hand the channel back to the embedder. 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (callback_thread_task_runner.get()) { 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) callback_thread_task_runner->PostTask( 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FROM_HERE, base::Bind(callback, channel_info.release())); 9523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } else { 9623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) callback.Run(channel_info.release()); 9723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} // namespace 101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 10203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void Init(scoped_ptr<PlatformSupport> platform_support) { 10303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) system::entrypoints::SetCore(new system::Core(platform_support.Pass())); 104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 1066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// TODO(vtl): Write tests for this. 1076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ScopedMessagePipeHandle CreateChannelOnIOThread( 1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ScopedPlatformHandle platform_handle, 1096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ChannelInfo** channel_info) { 1106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(platform_handle.is_valid()); 1116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(channel_info); 1126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<system::ChannelEndpoint> channel_endpoint; 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<system::MessagePipeDispatcher> dispatcher = 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci system::MessagePipeDispatcher::CreateRemoteMessagePipe(&channel_endpoint); 1166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) system::Core* core = system::entrypoints::GetCore(); 1186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(core); 1196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ScopedMessagePipeHandle rv( 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MessagePipeHandle(core->AddDispatcher(dispatcher))); 1216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) *channel_info = new ChannelInfo(); 1236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) (*channel_info)->channel = 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MakeChannel(core, platform_handle.Pass(), channel_endpoint); 1256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return rv.Pass(); 1276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 1286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 12923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)ScopedMessagePipeHandle CreateChannel( 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedPlatformHandle platform_handle, 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<base::TaskRunner> io_thread_task_runner, 13223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DidCreateChannelCallback callback, 13323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_refptr<base::TaskRunner> callback_thread_task_runner) { 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(platform_handle.is_valid()); 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<system::ChannelEndpoint> channel_endpoint; 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<system::MessagePipeDispatcher> dispatcher = 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci system::MessagePipeDispatcher::CreateRemoteMessagePipe(&channel_endpoint); 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 140a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch system::Core* core = system::entrypoints::GetCore(); 141a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch DCHECK(core); 14223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ScopedMessagePipeHandle rv( 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MessagePipeHandle(core->AddDispatcher(dispatcher))); 1446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_ptr<ChannelInfo> channel_info(new ChannelInfo()); 1466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) channel_info->io_thread_task_runner = io_thread_task_runner; 1476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 14823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (rv.is_valid()) { 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) io_thread_task_runner->PostTask(FROM_HERE, 1506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::Bind(&CreateChannelHelper, 15103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::Unretained(core), 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Passed(&platform_handle), 1536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::Passed(&channel_info), 1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci channel_endpoint, 15523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) callback, 15623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) callback_thread_task_runner)); 1576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } else { 1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (callback_thread_task_runner.get() ? callback_thread_task_runner 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : io_thread_task_runner) 1606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ->PostTask(FROM_HERE, base::Bind(callback, channel_info.release())); 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 16323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return rv.Pass(); 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DestroyChannelOnIOThread(ChannelInfo* channel_info) { 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(channel_info); 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!channel_info->channel.get()) { 169010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Presumably, |Init()| on the channel failed. 170010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 171010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 172010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) channel_info->channel->Shutdown(); 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delete channel_info; 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// TODO(vtl): Write tests for this. 1786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void DestroyChannel(ChannelInfo* channel_info) { 1796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(channel_info); 1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(channel_info->io_thread_task_runner.get()); 1816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!channel_info->channel.get()) { 1836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Presumably, |Init()| on the channel failed. 1846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return; 1856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 1866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) channel_info->channel->WillShutdownSoon(); 1886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) channel_info->io_thread_task_runner->PostTask( 1896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) FROM_HERE, base::Bind(&DestroyChannelOnIOThread, channel_info)); 1906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 1916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void WillDestroyChannelSoon(ChannelInfo* channel_info) { 1936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(channel_info); 1946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) channel_info->channel->WillShutdownSoon(); 1956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 1966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)MojoResult CreatePlatformHandleWrapper( 198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScopedPlatformHandle platform_handle, 199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MojoHandle* platform_handle_wrapper_handle) { 200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(platform_handle_wrapper_handle); 201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<system::Dispatcher> dispatcher( 203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new system::PlatformHandleDispatcher(platform_handle.Pass())); 204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) system::Core* core = system::entrypoints::GetCore(); 206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(core); 207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MojoHandle h = core->AddDispatcher(dispatcher); 208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (h == MOJO_HANDLE_INVALID) { 209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) LOG(ERROR) << "Handle table full"; 210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) dispatcher->Close(); 211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return MOJO_RESULT_RESOURCE_EXHAUSTED; 212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *platform_handle_wrapper_handle = h; 215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return MOJO_RESULT_OK; 216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)MojoResult PassWrappedPlatformHandle(MojoHandle platform_handle_wrapper_handle, 219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ScopedPlatformHandle* platform_handle) { 220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(platform_handle); 221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) system::Core* core = system::entrypoints::GetCore(); 223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(core); 224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<system::Dispatcher> dispatcher( 225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) core->GetDispatcher(platform_handle_wrapper_handle)); 2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!dispatcher.get()) 227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return MOJO_RESULT_INVALID_ARGUMENT; 228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (dispatcher->GetType() != system::Dispatcher::kTypePlatformHandle) 230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return MOJO_RESULT_INVALID_ARGUMENT; 231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *platform_handle = 2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) static_cast<system::PlatformHandleDispatcher*>(dispatcher.get()) 2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ->PassPlatformHandle() 2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) .Pass(); 236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return MOJO_RESULT_OK; 237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace embedder 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace mojo 241