forked from keyou/chromium_demo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdemo_mojo_single_process.cc
144 lines (134 loc) · 5.4 KB
/
demo_mojo_single_process.cc
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include <base/logging.h>
#include "base/command_line.h"
#include "base/message_loop/message_loop.h"
#include <base/threading/thread.h>
#include <mojo/core/embedder/embedder.h>
#include <mojo/core/embedder/scoped_ipc_support.h>
#include "mojo/public/c/system/buffer.h"
#include "mojo/public/c/system/data_pipe.h"
#include "mojo/public/c/system/message_pipe.h"
#include "mojo/public/cpp/system/buffer.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "mojo/public/cpp/system/message_pipe.h"
#include "mojo/public/cpp/system/simple_watcher.h"
#include "mojo/public/cpp/system/wait.h"
int main(int argc, char** argv) {
// 初始化CommandLine,DataPipe 依赖它
base::CommandLine::Init(argc, argv);
mojo::core::Init();
base::Thread ipc_thread("ipc!");
ipc_thread.StartWithOptions(
base::Thread::Options(base::MessagePumpType::IO, 0));
// As long as this object is alive, all Mojo API surface relevant to IPC
// connections is usable, and message pipes which span a process boundary will
// continue to function.
mojo::core::ScopedIPCSupport ipc_support(
ipc_thread.task_runner(),
mojo::core::ScopedIPCSupport::ShutdownPolicy::CLEAN);
// 使用 C 接口创建一条MessagePipe
// MessagePipe
// 只是一对数字,只用于ID标识,并不对应任何系统资源,并且该行为在单进程和多进程中都是一致的
// 因此可以非常快速,不可能失败的,创建大量的MessagePipe。
MojoHandle sender_handle, receiver_handle;
MojoResult result =
MojoCreateMessagePipe(NULL, &sender_handle, &receiver_handle);
DCHECK_EQ(result, MOJO_RESULT_OK);
// 使用 C 接口发送一条消息
{
MojoMessageHandle message;
result = MojoCreateMessage(nullptr, &message);
DCHECK_EQ(result, MOJO_RESULT_OK);
MojoAppendMessageDataOptions options;
options.struct_size = sizeof(options);
options.flags = MOJO_APPEND_MESSAGE_DATA_FLAG_COMMIT_SIZE;
void* buffer;
uint32_t buffer_size;
result = MojoAppendMessageData(message, 6, nullptr, 0, &options, &buffer,
&buffer_size);
DCHECK_EQ(result, MOJO_RESULT_OK);
memcpy(buffer, "hello", 6);
LOG(INFO) << "send: " << (const char*)buffer;
result = MojoWriteMessage(sender_handle, message, nullptr);
DCHECK_EQ(result, MOJO_RESULT_OK);
}
// 使用 C 接口接收一条消息
{
MojoMessageHandle message;
MojoResult result = MojoReadMessage(receiver_handle, nullptr, &message);
DCHECK_EQ(result, MOJO_RESULT_OK);
void* buffer = NULL;
uint32_t num_bytes;
result = MojoGetMessageData(message, nullptr, &buffer, &num_bytes, nullptr,
nullptr);
LOG(INFO) << "receive: " << (const char*)buffer;
}
// 使用C++接口创建一条 MessagePipe
mojo::MessagePipe pipe;
// 使用 C++ 接口发送一条消息
{
const char kMessage[] = "HELLO";
result =
mojo::WriteMessageRaw(pipe.handle0.get(), kMessage, sizeof(kMessage),
nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE);
DCHECK_EQ(result, MOJO_RESULT_OK);
LOG(INFO) << "send: " << kMessage;
}
// 使用 C++ 接口接收一条消息
{
std::vector<uint8_t> data;
result = mojo::ReadMessageRaw(pipe.handle1.get(), &data, nullptr,
MOJO_READ_MESSAGE_FLAG_NONE);
DCHECK_EQ(result, MOJO_RESULT_OK);
LOG(INFO) << "receive msg: " << (char*)&data[0];
}
// 使用 C++ 接口创建一条 DataPipe,DataPipe 是单向的
mojo::ScopedDataPipeProducerHandle producer;
mojo::ScopedDataPipeConsumerHandle consumer;
// 内部涉及系统资源的分配,可能会失败,因此不建议使用 mojo::DataPipe
// 来创建,会导致崩溃
result = mojo::CreateDataPipe(nullptr, &producer, &consumer);
// 使用 DataPipe 写数据
{
const char kMessage[] = "DataPipe";
uint32_t length = sizeof(kMessage);
result = producer->WriteData(kMessage, &length, MOJO_WRITE_DATA_FLAG_NONE);
DCHECK_EQ(result, MOJO_RESULT_OK);
LOG(INFO) << "send data: " << kMessage;
}
// 使用 DataPipe 读数据
{
char buffer[100];
uint32_t num_bytes = 100;
result = consumer->ReadData(buffer, &num_bytes, MOJO_READ_DATA_FLAG_NONE);
DCHECK_EQ(result, MOJO_RESULT_OK);
LOG(INFO) << "receive data: " << buffer;
}
// 使用 C++ 接口创建一个 SharedBuffer
// Shared Buffer 内部也使用 Shared Memory 实现
mojo::ScopedSharedBufferHandle buffer =
mojo::SharedBufferHandle::Create(4096);
// clone一个buffer的句柄,该句柄和buffer指向相同的内存,内部有引用计数
// 当计数为0的时候,句柄指向的内存会被销毁
// 这里只是为了演示Clone,并不是必须的
mojo::ScopedSharedBufferHandle buffer_clone =
buffer->Clone(mojo::SharedBufferHandle::AccessMode::READ_WRITE);
// 向 SharedBuffer 写数据
{
const std::string kMessage("SharedBuffer\0", 13);
mojo::ScopedSharedBufferMapping mapping = buffer->Map(kMessage.length());
DCHECK(mapping);
std::copy(kMessage.begin(), kMessage.end(),
static_cast<char*>(mapping.get()));
LOG(INFO) << "write buffer: " << kMessage;
}
// 从 SharedBuffer 读数据
{
mojo::ScopedSharedBufferMapping mapping = buffer_clone ->Map(64);
LOG(INFO) << "read buffer: " << static_cast<char*>(mapping.get());
}
// 创建消息循环
base::MessageLoop message_loop;
base::RunLoop run_loop;
run_loop.Run();
return 0;
}