summaryrefslogtreecommitdiffstats
path: root/mojo/system/embedder/embedder.cc
blob: 03b5440193844b3efcff3682a35b8e0132e13132 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "mojo/system/embedder/embedder.h"

#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "mojo/system/channel.h"
#include "mojo/system/core_impl.h"
#include "mojo/system/message_pipe.h"
#include "mojo/system/message_pipe_dispatcher.h"

namespace mojo {
namespace embedder {

struct ChannelInfo {
  scoped_refptr<system::Channel> channel;
};

static void CreateChannelOnIOThread(
    ScopedPlatformHandle platform_handle,
    scoped_refptr<system::MessagePipe> message_pipe,
    DidCreateChannelOnIOThreadCallback callback) {
  CHECK(platform_handle.is_valid());

  scoped_ptr<ChannelInfo> channel_info(new ChannelInfo);

  // Create and initialize a |system::Channel|.
  channel_info->channel = new system::Channel();
  bool success = channel_info->channel->Init(platform_handle.Pass());
  DCHECK(success);

  // Attach the message pipe endpoint.
  system::MessageInTransit::EndpointId endpoint_id =
      channel_info->channel->AttachMessagePipeEndpoint(message_pipe, 1);
  DCHECK_EQ(endpoint_id, system::Channel::kBootstrapEndpointId);
  channel_info->channel->RunMessagePipeEndpoint(
      system::Channel::kBootstrapEndpointId,
      system::Channel::kBootstrapEndpointId);

  // Hand the channel back to the embedder.
  callback.Run(channel_info.release());
}

void Init() {
  Core::Init(new system::CoreImpl());
}

MojoHandle CreateChannel(
    ScopedPlatformHandle platform_handle,
    scoped_refptr<base::TaskRunner> io_thread_task_runner,
    DidCreateChannelOnIOThreadCallback callback) {
  DCHECK(platform_handle.is_valid());

  std::pair<scoped_refptr<system::MessagePipeDispatcher>,
            scoped_refptr<system::MessagePipe> > remote_message_pipe =
      system::MessagePipeDispatcher::CreateRemoteMessagePipe();

  system::CoreImpl* core_impl = static_cast<system::CoreImpl*>(Core::Get());
  DCHECK(core_impl);
  MojoHandle rv = core_impl->AddDispatcher(remote_message_pipe.first);
  // TODO(vtl): Do we properly handle the failure case here?
  if (rv != MOJO_HANDLE_INVALID) {
    io_thread_task_runner->PostTask(FROM_HERE,
                                    base::Bind(&CreateChannelOnIOThread,
                                               base::Passed(&platform_handle),
                                               remote_message_pipe.second,
                                               callback));
  }
  return rv;
}

void DestroyChannelOnIOThread(ChannelInfo* channel_info) {
  DCHECK(channel_info);
  DCHECK(channel_info->channel.get());
  channel_info->channel->Shutdown();
  delete channel_info;
}

}  // namespace embedder
}  // namespace mojo