blob: 7b61d04b58118c7a9fb4ea9647529fbf124b3d3b [file] [log] [blame]
Zachary Anderson70d85e92014-12-02 21:59:36 -08001// Copyright 2014 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 <stdio.h>
6#include <string.h>
James Robinsona6a13fb2015-10-19 15:37:01 -07007
8#include <memory>
Zachary Anderson42969152015-01-26 14:47:52 -08009#include <vector>
Zachary Anderson70d85e92014-12-02 21:59:36 -080010
Zachary Anderson70d85e92014-12-02 21:59:36 -080011#include "dart/runtime/include/dart_api.h"
Zachary Anderson70d85e92014-12-02 21:59:36 -080012#include "mojo/public/c/system/core.h"
James Robinsona6a13fb2015-10-19 15:37:01 -070013#include "mojo/public/cpp/environment/logging.h"
Jim Beveridge84a66f32015-01-08 10:18:15 -080014#include "mojo/public/cpp/system/core.h"
James Robinsona6a13fb2015-10-19 15:37:01 -070015#include "mojo/public/cpp/system/macros.h"
Zachary Anderson70d85e92014-12-02 21:59:36 -080016
17namespace mojo {
18namespace dart {
19
John McCutchan51728422015-10-29 07:13:36 -070020#define REGISTER_FUNCTION(name, count) \
21 { "" #name, name, count },
22#define DECLARE_FUNCTION(name, count) \
23 extern void name(Dart_NativeArguments args);
24
Jim Beveridge84a66f32015-01-08 10:18:15 -080025#define MOJO_NATIVE_LIST(V) \
26 V(MojoSharedBuffer_Create, 2) \
27 V(MojoSharedBuffer_Duplicate, 2) \
28 V(MojoSharedBuffer_Map, 5) \
29 V(MojoSharedBuffer_Unmap, 1) \
30 V(MojoDataPipe_Create, 3) \
31 V(MojoDataPipe_WriteData, 4) \
32 V(MojoDataPipe_BeginWriteData, 3) \
33 V(MojoDataPipe_EndWriteData, 2) \
34 V(MojoDataPipe_ReadData, 4) \
35 V(MojoDataPipe_BeginReadData, 3) \
36 V(MojoDataPipe_EndReadData, 2) \
37 V(MojoMessagePipe_Create, 1) \
38 V(MojoMessagePipe_Write, 5) \
39 V(MojoMessagePipe_Read, 5) \
Zachary Anderson321bf1a2015-11-06 15:59:07 -080040 V(MojoMessagePipe_QueryAndRead, 3) \
Mitch Rudominer9f26bb42015-07-28 08:48:09 -070041 V(Mojo_GetTimeTicksNow, 0) \
Jim Beveridge84a66f32015-01-08 10:18:15 -080042 V(MojoHandle_Close, 1) \
43 V(MojoHandle_Wait, 3) \
Zachary Anderson241ff8a2015-10-27 15:06:13 -070044 V(MojoHandle_RegisterFinalizer, 2) \
Jim Beveridge84a66f32015-01-08 10:18:15 -080045 V(MojoHandle_WaitMany, 3) \
Zachary Andersone54a9192015-10-07 09:27:42 -070046 V(MojoHandleWatcher_GrowStateArrays, 1) \
47 V(MojoHandleWatcher_WaitMany, 2) \
Jim Beveridge84a66f32015-01-08 10:18:15 -080048 V(MojoHandleWatcher_SendControlData, 4) \
49 V(MojoHandleWatcher_RecvControlData, 1) \
50 V(MojoHandleWatcher_SetControlHandle, 1) \
51 V(MojoHandleWatcher_GetControlHandle, 0)
Zachary Anderson70d85e92014-12-02 21:59:36 -080052
53MOJO_NATIVE_LIST(DECLARE_FUNCTION);
54
55static struct NativeEntries {
56 const char* name;
57 Dart_NativeFunction function;
58 int argument_count;
59} MojoEntries[] = {MOJO_NATIVE_LIST(REGISTER_FUNCTION)};
60
61Dart_NativeFunction MojoNativeLookup(Dart_Handle name,
62 int argument_count,
63 bool* auto_setup_scope) {
64 const char* function_name = nullptr;
65 Dart_Handle result = Dart_StringToCString(name, &function_name);
66 DART_CHECK_VALID(result);
James Robinsona6a13fb2015-10-19 15:37:01 -070067 assert(function_name != nullptr);
68 assert(auto_setup_scope != nullptr);
Zachary Anderson70d85e92014-12-02 21:59:36 -080069 *auto_setup_scope = true;
James Robinsona6a13fb2015-10-19 15:37:01 -070070 size_t num_entries = MOJO_ARRAYSIZE(MojoEntries);
Zachary Anderson70d85e92014-12-02 21:59:36 -080071 for (size_t i = 0; i < num_entries; ++i) {
72 const struct NativeEntries& entry = MojoEntries[i];
73 if (!strcmp(function_name, entry.name) &&
74 (entry.argument_count == argument_count)) {
75 return entry.function;
76 }
77 }
78 return nullptr;
79}
80
81const uint8_t* MojoNativeSymbol(Dart_NativeFunction nf) {
James Robinsona6a13fb2015-10-19 15:37:01 -070082 size_t num_entries = MOJO_ARRAYSIZE(MojoEntries);
Zachary Anderson70d85e92014-12-02 21:59:36 -080083 for (size_t i = 0; i < num_entries; ++i) {
84 const struct NativeEntries& entry = MojoEntries[i];
85 if (entry.function == nf) {
86 return reinterpret_cast<const uint8_t*>(entry.name);
87 }
88 }
89 return nullptr;
90}
91
92static void SetNullReturn(Dart_NativeArguments arguments) {
93 Dart_SetReturnValue(arguments, Dart_Null());
94}
95
96static void SetInvalidArgumentReturn(Dart_NativeArguments arguments) {
97 Dart_SetIntegerReturnValue(
98 arguments, static_cast<int64_t>(MOJO_RESULT_INVALID_ARGUMENT));
99}
100
Zachary Anderson92c24022015-03-23 11:04:03 -0700101static Dart_Handle SignalsStateToDart(const MojoHandleSignalsState& state) {
102 Dart_Handle list = Dart_NewList(2);
103 Dart_Handle arg0 = Dart_NewInteger(state.satisfied_signals);
104 Dart_Handle arg1 = Dart_NewInteger(state.satisfiable_signals);
105 Dart_ListSetAt(list, 0, arg0);
106 Dart_ListSetAt(list, 1, arg1);
107 return list;
Jim Beveridge84a66f32015-01-08 10:18:15 -0800108}
109
Zachary Anderson70d85e92014-12-02 21:59:36 -0800110#define CHECK_INTEGER_ARGUMENT(args, num, result, failure) \
111 { \
112 Dart_Handle __status; \
113 __status = Dart_GetNativeIntegerArgument(args, num, result); \
114 if (Dart_IsError(__status)) { \
115 Set##failure##Return(arguments); \
116 return; \
117 } \
118 } \
119
120struct CloserCallbackPeer {
121 MojoHandle handle;
122};
123
124static void MojoHandleCloserCallback(void* isolate_data,
125 Dart_WeakPersistentHandle handle,
126 void* peer) {
127 CloserCallbackPeer* callback_peer =
128 reinterpret_cast<CloserCallbackPeer*>(peer);
129 if (callback_peer->handle != MOJO_HANDLE_INVALID) {
Zachary Anderson940e4aa2015-11-17 09:38:37 -0800130 MojoClose(callback_peer->handle);
Zachary Anderson70d85e92014-12-02 21:59:36 -0800131 }
132 delete callback_peer;
133}
134
Zachary Anderson92c24022015-03-23 11:04:03 -0700135// Setup a weak persistent handle for a MojoHandle that calls MojoClose on the
136// handle when the MojoHandle is GC'd or the VM is going down.
Zachary Anderson241ff8a2015-10-27 15:06:13 -0700137void MojoHandle_RegisterFinalizer(Dart_NativeArguments arguments) {
Zachary Anderson70d85e92014-12-02 21:59:36 -0800138 Dart_Handle mojo_handle_instance = Dart_GetNativeArgument(arguments, 0);
139 if (!Dart_IsInstance(mojo_handle_instance)) {
140 SetInvalidArgumentReturn(arguments);
141 return;
142 }
Zachary Anderson70d85e92014-12-02 21:59:36 -0800143
144 int64_t raw_handle = static_cast<int64_t>(MOJO_HANDLE_INVALID);
Zachary Anderson92c24022015-03-23 11:04:03 -0700145 CHECK_INTEGER_ARGUMENT(arguments, 1, &raw_handle, InvalidArgument);
Zachary Anderson70d85e92014-12-02 21:59:36 -0800146 if (raw_handle == static_cast<int64_t>(MOJO_HANDLE_INVALID)) {
147 SetInvalidArgumentReturn(arguments);
148 return;
149 }
150
Zachary Andersonb7959af2015-03-12 09:18:21 -0700151 // Add the handle to this isolate's set.
152 MojoHandle handle = static_cast<MojoHandle>(raw_handle);
Zachary Andersonb7959af2015-03-12 09:18:21 -0700153
154 // Set up a finalizer.
Zachary Anderson70d85e92014-12-02 21:59:36 -0800155 CloserCallbackPeer* callback_peer = new CloserCallbackPeer();
Zachary Andersonb7959af2015-03-12 09:18:21 -0700156 callback_peer->handle = handle;
Zachary Anderson70d85e92014-12-02 21:59:36 -0800157 Dart_NewWeakPersistentHandle(mojo_handle_instance,
158 reinterpret_cast<void*>(callback_peer),
159 sizeof(CloserCallbackPeer),
160 MojoHandleCloserCallback);
161 Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(MOJO_RESULT_OK));
162}
163
Mitch Rudominer9f26bb42015-07-28 08:48:09 -0700164void Mojo_GetTimeTicksNow(Dart_NativeArguments arguments) {
165 MojoTimeTicks ticks = MojoGetTimeTicksNow();
166 Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(ticks));
167}
168
Zachary Anderson70d85e92014-12-02 21:59:36 -0800169void MojoHandle_Close(Dart_NativeArguments arguments) {
Zachary Andersonb7959af2015-03-12 09:18:21 -0700170 int64_t raw_handle;
171 CHECK_INTEGER_ARGUMENT(arguments, 0, &raw_handle, InvalidArgument);
Zachary Anderson70d85e92014-12-02 21:59:36 -0800172
Zachary Andersonb7959af2015-03-12 09:18:21 -0700173 // Remove the handle from this isolate's set.
174 MojoHandle handle = static_cast<MojoHandle>(raw_handle);
Zachary Andersonb7959af2015-03-12 09:18:21 -0700175 MojoResult res = MojoClose(handle);
Zachary Anderson70d85e92014-12-02 21:59:36 -0800176
177 Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
178}
179
180void MojoHandle_Wait(Dart_NativeArguments arguments) {
181 int64_t handle = 0;
182 int64_t signals = 0;
183 int64_t deadline = 0;
184 CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, InvalidArgument);
185 CHECK_INTEGER_ARGUMENT(arguments, 1, &signals, InvalidArgument);
186 CHECK_INTEGER_ARGUMENT(arguments, 2, &deadline, InvalidArgument);
187
Jim Beveridge84a66f32015-01-08 10:18:15 -0800188 MojoHandleSignalsState state;
189 MojoResult r = mojo::Wait(mojo::Handle(static_cast<MojoHandle>(handle)),
190 static_cast<MojoHandleSignals>(signals),
191 static_cast<MojoDeadline>(deadline), &state);
Zachary Anderson70d85e92014-12-02 21:59:36 -0800192
Jim Beveridge84a66f32015-01-08 10:18:15 -0800193 // The return value is structured as a list of length 2:
194 // [0] MojoResult
195 // [1] MojoHandleSignalsState. (may be null)
196 Dart_Handle list = Dart_NewList(2);
197 Dart_ListSetAt(list, 0, Dart_NewInteger(r));
198 if (mojo::WaitManyResult(r).AreSignalsStatesValid()) {
Zachary Anderson92c24022015-03-23 11:04:03 -0700199 Dart_ListSetAt(list, 1, SignalsStateToDart(state));
Jim Beveridge84a66f32015-01-08 10:18:15 -0800200 } else {
201 Dart_ListSetAt(list, 1, Dart_Null());
202 }
203 Dart_SetReturnValue(arguments, list);
Zachary Anderson70d85e92014-12-02 21:59:36 -0800204}
205
206void MojoHandle_WaitMany(Dart_NativeArguments arguments) {
Zachary Anderson70d85e92014-12-02 21:59:36 -0800207 int64_t deadline = 0;
208 Dart_Handle handles = Dart_GetNativeArgument(arguments, 0);
209 Dart_Handle signals = Dart_GetNativeArgument(arguments, 1);
Jim Beveridge84a66f32015-01-08 10:18:15 -0800210 CHECK_INTEGER_ARGUMENT(arguments, 2, &deadline, InvalidArgument);
Zachary Anderson70d85e92014-12-02 21:59:36 -0800211
212 if (!Dart_IsList(handles) || !Dart_IsList(signals)) {
213 SetInvalidArgumentReturn(arguments);
214 return;
215 }
216
217 intptr_t handles_len = 0;
218 intptr_t signals_len = 0;
219 Dart_ListLength(handles, &handles_len);
220 Dart_ListLength(signals, &signals_len);
Jim Beveridge84a66f32015-01-08 10:18:15 -0800221 if (handles_len != signals_len) {
Zachary Anderson70d85e92014-12-02 21:59:36 -0800222 SetInvalidArgumentReturn(arguments);
223 return;
224 }
225
Jim Beveridge84a66f32015-01-08 10:18:15 -0800226 std::vector<mojo::Handle> mojo_handles(handles_len);
227 std::vector<MojoHandleSignals> mojo_signals(handles_len);
Zachary Anderson70d85e92014-12-02 21:59:36 -0800228
Jim Beveridge84a66f32015-01-08 10:18:15 -0800229 for (int i = 0; i < handles_len; i++) {
Zachary Anderson70d85e92014-12-02 21:59:36 -0800230 Dart_Handle dart_handle = Dart_ListGetAt(handles, i);
231 Dart_Handle dart_signal = Dart_ListGetAt(signals, i);
232 if (!Dart_IsInteger(dart_handle) || !Dart_IsInteger(dart_signal)) {
233 SetInvalidArgumentReturn(arguments);
234 return;
235 }
236 int64_t mojo_handle = 0;
237 int64_t mojo_signal = 0;
238 Dart_IntegerToInt64(dart_handle, &mojo_handle);
239 Dart_IntegerToInt64(dart_signal, &mojo_signal);
Jim Beveridge84a66f32015-01-08 10:18:15 -0800240 mojo_handles[i] = mojo::Handle(mojo_handle);
Zachary Anderson70d85e92014-12-02 21:59:36 -0800241 mojo_signals[i] = static_cast<MojoHandleSignals>(mojo_signal);
242 }
243
Jim Beveridge84a66f32015-01-08 10:18:15 -0800244 std::vector<MojoHandleSignalsState> states(handles_len);
245 mojo::WaitManyResult wmr = mojo::WaitMany(
246 mojo_handles, mojo_signals, static_cast<MojoDeadline>(deadline), &states);
247
Jim Beveridge84a66f32015-01-08 10:18:15 -0800248 // The return value is structured as a list of length 3:
249 // [0] MojoResult
250 // [1] index of handle that caused a return (may be null)
251 // [2] list of MojoHandleSignalsState. (may be null)
252 Dart_Handle list = Dart_NewList(3);
253 Dart_ListSetAt(list, 0, Dart_NewInteger(wmr.result));
254 if (wmr.IsIndexValid())
255 Dart_ListSetAt(list, 1, Dart_NewInteger(wmr.index));
256 else
257 Dart_ListSetAt(list, 1, Dart_Null());
258 if (wmr.AreSignalsStatesValid()) {
259 Dart_Handle stateList = Dart_NewList(handles_len);
260 for (int i = 0; i < handles_len; i++) {
Zachary Anderson92c24022015-03-23 11:04:03 -0700261 Dart_ListSetAt(stateList, i, SignalsStateToDart(states[i]));
Jim Beveridge84a66f32015-01-08 10:18:15 -0800262 }
263 Dart_ListSetAt(list, 2, stateList);
264 } else {
265 Dart_ListSetAt(list, 2, Dart_Null());
266 }
267 Dart_SetReturnValue(arguments, list);
Zachary Anderson70d85e92014-12-02 21:59:36 -0800268}
269
270void MojoSharedBuffer_Create(Dart_NativeArguments arguments) {
271 int64_t num_bytes = 0;
272 int64_t flags = 0;
273 CHECK_INTEGER_ARGUMENT(arguments, 0, &num_bytes, Null);
274 CHECK_INTEGER_ARGUMENT(arguments, 1, &flags, Null);
275
276 MojoCreateSharedBufferOptions options;
277 options.struct_size = sizeof(MojoCreateSharedBufferOptions);
278 options.flags = static_cast<MojoCreateSharedBufferOptionsFlags>(flags);
279
280 MojoHandle out = MOJO_HANDLE_INVALID;;
281 MojoResult res = MojoCreateSharedBuffer(
282 &options, static_cast<int32_t>(num_bytes), &out);
283
284 Dart_Handle list = Dart_NewList(2);
285 Dart_ListSetAt(list, 0, Dart_NewInteger(res));
286 Dart_ListSetAt(list, 1, Dart_NewInteger(out));
287 Dart_SetReturnValue(arguments, list);
288}
289
290void MojoSharedBuffer_Duplicate(Dart_NativeArguments arguments) {
291 int64_t handle = 0;
292 int64_t flags = 0;
293 CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
294 CHECK_INTEGER_ARGUMENT(arguments, 1, &flags, Null);
295
296 MojoDuplicateBufferHandleOptions options;
297 options.struct_size = sizeof(MojoDuplicateBufferHandleOptions);
298 options.flags = static_cast<MojoDuplicateBufferHandleOptionsFlags>(flags);
299
300 MojoHandle out = MOJO_HANDLE_INVALID;;
301 MojoResult res = MojoDuplicateBufferHandle(
302 static_cast<MojoHandle>(handle), &options, &out);
303
304 Dart_Handle list = Dart_NewList(2);
305 Dart_ListSetAt(list, 0, Dart_NewInteger(res));
306 Dart_ListSetAt(list, 1, Dart_NewInteger(out));
307 Dart_SetReturnValue(arguments, list);
308}
309
310static void MojoBufferUnmapCallback(void* isolate_data,
311 Dart_WeakPersistentHandle handle,
312 void* peer) {
313 MojoUnmapBuffer(peer);
314}
315
316void MojoSharedBuffer_Map(Dart_NativeArguments arguments) {
317 int64_t handle = 0;
318 int64_t offset = 0;
319 int64_t num_bytes = 0;
320 int64_t flags = 0;
321 Dart_Handle mojo_buffer = Dart_GetNativeArgument(arguments, 0);
322 CHECK_INTEGER_ARGUMENT(arguments, 1, &handle, Null);
323 CHECK_INTEGER_ARGUMENT(arguments, 2, &offset, Null);
324 CHECK_INTEGER_ARGUMENT(arguments, 3, &num_bytes, Null);
325 CHECK_INTEGER_ARGUMENT(arguments, 4, &flags, Null);
326
327 void* out;
328 MojoResult res = MojoMapBuffer(static_cast<MojoHandle>(handle),
329 offset,
330 num_bytes,
331 &out,
332 static_cast<MojoMapBufferFlags>(flags));
333
334 Dart_Handle list = Dart_NewList(2);
335 Dart_Handle typed_data;
336 if (res == MOJO_RESULT_OK) {
337 typed_data = Dart_NewExternalTypedData(
338 Dart_TypedData_kByteData, out, num_bytes);
339 Dart_NewWeakPersistentHandle(
340 mojo_buffer, out, num_bytes, MojoBufferUnmapCallback);
341 } else {
342 typed_data = Dart_Null();
343 }
344 Dart_ListSetAt(list, 0, Dart_NewInteger(res));
345 Dart_ListSetAt(list, 1, typed_data);
346 Dart_SetReturnValue(arguments, list);
347}
348
349void MojoSharedBuffer_Unmap(Dart_NativeArguments arguments) {
350 Dart_Handle typed_data = Dart_GetNativeArgument(arguments, 0);
351 if (Dart_GetTypeOfExternalTypedData(typed_data) == Dart_TypedData_kInvalid) {
352 SetInvalidArgumentReturn(arguments);
353 return;
354 }
355
356 Dart_TypedData_Type typ;
357 void *data;
358 intptr_t len;
359 Dart_TypedDataAcquireData(typed_data, &typ, &data, &len);
360 MojoResult res = MojoUnmapBuffer(data);
361 Dart_TypedDataReleaseData(typed_data);
362
363 Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
364}
365
366void MojoDataPipe_Create(Dart_NativeArguments arguments) {
367 int64_t element_bytes = 0;
368 int64_t capacity_bytes = 0;
369 int64_t flags = 0;
370 CHECK_INTEGER_ARGUMENT(arguments, 0, &element_bytes, Null);
371 CHECK_INTEGER_ARGUMENT(arguments, 1, &capacity_bytes, Null);
372 CHECK_INTEGER_ARGUMENT(arguments, 2, &flags, Null);
373
374 MojoCreateDataPipeOptions options;
375 options.struct_size = sizeof(MojoCreateDataPipeOptions);
376 options.flags = static_cast<MojoCreateDataPipeOptionsFlags>(flags);
377 options.element_num_bytes = static_cast<uint32_t>(element_bytes);
378 options.capacity_num_bytes = static_cast<uint32_t>(capacity_bytes);
379
380 MojoHandle producer = MOJO_HANDLE_INVALID;
381 MojoHandle consumer = MOJO_HANDLE_INVALID;
382 MojoResult res = MojoCreateDataPipe(&options, &producer, &consumer);
383
384 Dart_Handle list = Dart_NewList(3);
385 Dart_ListSetAt(list, 0, Dart_NewInteger(res));
386 Dart_ListSetAt(list, 1, Dart_NewInteger(producer));
387 Dart_ListSetAt(list, 2, Dart_NewInteger(consumer));
388 Dart_SetReturnValue(arguments, list);
389}
390
391void MojoDataPipe_WriteData(Dart_NativeArguments arguments) {
392 int64_t handle = 0;
393 CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
394
395 Dart_Handle typed_data = Dart_GetNativeArgument(arguments, 1);
396 if (!Dart_IsTypedData(typed_data)) {
397 SetNullReturn(arguments);
398 return;
399 }
400
401 int64_t num_bytes = 0;
402 CHECK_INTEGER_ARGUMENT(arguments, 2, &num_bytes, Null);
403 if (num_bytes <= 0) {
404 SetNullReturn(arguments);
405 return;
406 }
407
408 int64_t flags = 0;
409 CHECK_INTEGER_ARGUMENT(arguments, 3, &flags, Null);
410
411 Dart_TypedData_Type type;
412 void* data;
413 intptr_t data_length;
414 Dart_TypedDataAcquireData(typed_data, &type, &data, &data_length);
415 uint32_t length = static_cast<uint32_t>(num_bytes);
416 MojoResult res = MojoWriteData(
417 static_cast<MojoHandle>(handle),
418 data,
419 &length,
420 static_cast<MojoWriteDataFlags>(flags));
421 Dart_TypedDataReleaseData(typed_data);
422
423 Dart_Handle list = Dart_NewList(2);
424 Dart_ListSetAt(list, 0, Dart_NewInteger(res));
425 Dart_ListSetAt(list, 1, Dart_NewInteger(length));
426 Dart_SetReturnValue(arguments, list);
427}
428
429void MojoDataPipe_BeginWriteData(Dart_NativeArguments arguments) {
430 int64_t handle = 0;
431 int64_t buffer_bytes = 0;
432 int64_t flags = 0;
433 CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
434 CHECK_INTEGER_ARGUMENT(arguments, 1, &buffer_bytes, Null);
435 CHECK_INTEGER_ARGUMENT(arguments, 2, &flags, Null);
436
437 void* buffer;
438 uint32_t size = static_cast<uint32_t>(buffer_bytes);
439 MojoResult res = MojoBeginWriteData(
440 static_cast<MojoHandle>(handle),
441 &buffer,
442 &size,
443 static_cast<MojoWriteDataFlags>(flags));
444
445 Dart_Handle list = Dart_NewList(2);
446 Dart_Handle typed_data;
447 if (res == MOJO_RESULT_OK) {
448 typed_data = Dart_NewExternalTypedData(
449 Dart_TypedData_kByteData, buffer, size);
450 } else {
451 typed_data = Dart_Null();
452 }
453 Dart_ListSetAt(list, 0, Dart_NewInteger(res));
454 Dart_ListSetAt(list, 1, typed_data);
455 Dart_SetReturnValue(arguments, list);
456}
457
458void MojoDataPipe_EndWriteData(Dart_NativeArguments arguments) {
459 int64_t handle = 0;
460 int64_t num_bytes_written = 0;
461 CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, InvalidArgument);
462 CHECK_INTEGER_ARGUMENT(arguments, 1, &num_bytes_written, InvalidArgument);
463
464 MojoResult res = MojoEndWriteData(
465 static_cast<MojoHandle>(handle),
466 static_cast<uint32_t>(num_bytes_written));
467
468 Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
469}
470
471void MojoDataPipe_ReadData(Dart_NativeArguments arguments) {
472 int64_t handle = 0;
473 CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
474
475 Dart_Handle typed_data = Dart_GetNativeArgument(arguments, 1);
476 if (!Dart_IsTypedData(typed_data) && !Dart_IsNull(typed_data)) {
477 SetNullReturn(arguments);
478 return;
479 }
480 // When querying the amount of data available to read from the pipe,
481 // null is passed in for typed_data.
482
483 int64_t num_bytes = 0;
484 CHECK_INTEGER_ARGUMENT(arguments, 2, &num_bytes, Null);
485
486 int64_t flags = 0;
487 CHECK_INTEGER_ARGUMENT(arguments, 3, &flags, Null);
488
489 Dart_TypedData_Type typ;
490 void* data = nullptr;
491 intptr_t bdlen = 0;
492 if (!Dart_IsNull(typed_data)) {
493 Dart_TypedDataAcquireData(typed_data, &typ, &data, &bdlen);
494 }
495 uint32_t len = static_cast<uint32_t>(num_bytes);
496 MojoResult res = MojoReadData(
497 static_cast<MojoHandle>(handle),
498 data,
499 &len,
500 static_cast<MojoReadDataFlags>(flags));
501 if (!Dart_IsNull(typed_data)) {
502 Dart_TypedDataReleaseData(typed_data);
503 }
504
505 Dart_Handle list = Dart_NewList(2);
506 Dart_ListSetAt(list, 0, Dart_NewInteger(res));
507 Dart_ListSetAt(list, 1, Dart_NewInteger(len));
508 Dart_SetReturnValue(arguments, list);
509}
510
511void MojoDataPipe_BeginReadData(Dart_NativeArguments arguments) {
512 int64_t handle = 0;
513 int64_t buffer_bytes = 0;
514 int64_t flags = 0;
515 CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
516 CHECK_INTEGER_ARGUMENT(arguments, 1, &buffer_bytes, Null);
517 CHECK_INTEGER_ARGUMENT(arguments, 2, &flags, Null);
518
519 void* buffer;
520 uint32_t size = static_cast<uint32_t>(buffer_bytes);
521 MojoResult res = MojoBeginReadData(
522 static_cast<MojoHandle>(handle),
523 const_cast<const void**>(&buffer),
524 &size,
525 static_cast<MojoWriteDataFlags>(flags));
526
527 Dart_Handle list = Dart_NewList(2);
528 Dart_Handle typed_data;
529 if (res == MOJO_RESULT_OK) {
530 typed_data = Dart_NewExternalTypedData(
531 Dart_TypedData_kByteData, buffer, size);
532 } else {
533 typed_data = Dart_Null();
534 }
535 Dart_ListSetAt(list, 0, Dart_NewInteger(res));
536 Dart_ListSetAt(list, 1, typed_data);
537 Dart_SetReturnValue(arguments, list);
538}
539
540void MojoDataPipe_EndReadData(Dart_NativeArguments arguments) {
541 int64_t handle = 0;
542 int64_t num_bytes_read = 0;
543 CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, InvalidArgument);
544 CHECK_INTEGER_ARGUMENT(arguments, 1, &num_bytes_read, InvalidArgument);
545
546 MojoResult res = MojoEndReadData(
547 static_cast<MojoHandle>(handle),
548 static_cast<uint32_t>(num_bytes_read));
549
550 Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
551}
552
553void MojoMessagePipe_Create(Dart_NativeArguments arguments) {
554 int64_t flags = 0;
555 CHECK_INTEGER_ARGUMENT(arguments, 0, &flags, Null);
556
557 MojoCreateMessagePipeOptions options;
558 options.struct_size = sizeof(MojoCreateMessagePipeOptions);
559 options.flags = static_cast<MojoCreateMessagePipeOptionsFlags>(flags);
560
561 MojoHandle end1 = MOJO_HANDLE_INVALID;
562 MojoHandle end2 = MOJO_HANDLE_INVALID;
563 MojoResult res = MojoCreateMessagePipe(&options, &end1, &end2);
564
565 Dart_Handle list = Dart_NewList(3);
566 Dart_ListSetAt(list, 0, Dart_NewInteger(res));
567 Dart_ListSetAt(list, 1, Dart_NewInteger(end1));
568 Dart_ListSetAt(list, 2, Dart_NewInteger(end2));
569 Dart_SetReturnValue(arguments, list);
570}
571
572void MojoMessagePipe_Write(Dart_NativeArguments arguments) {
573 int64_t handle = 0;
574 CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, InvalidArgument);
575
576 Dart_Handle typed_data = Dart_GetNativeArgument(arguments, 1);
577 if (!Dart_IsTypedData(typed_data) && !Dart_IsNull(typed_data)) {
578 SetInvalidArgumentReturn(arguments);
579 return;
580 }
581
582 int64_t num_bytes = 0;
583 CHECK_INTEGER_ARGUMENT(arguments, 2, &num_bytes, InvalidArgument);
584 if ((Dart_IsNull(typed_data) && (num_bytes != 0)) ||
585 (!Dart_IsNull(typed_data) && (num_bytes <= 0))) {
586 SetInvalidArgumentReturn(arguments);
587 return;
588 }
589
590 Dart_Handle handles = Dart_GetNativeArgument(arguments, 3);
591 if (!Dart_IsList(handles) && !Dart_IsNull(handles)) {
592 SetInvalidArgumentReturn(arguments);
593 return;
594 }
595
596 int64_t flags = 0;
597 CHECK_INTEGER_ARGUMENT(arguments, 4, &flags, InvalidArgument);
598
599 // Grab the data if there is any.
600 Dart_TypedData_Type typ;
601 void* bytes = nullptr;
602 intptr_t bdlen = 0;
603 if (!Dart_IsNull(typed_data)) {
604 Dart_TypedDataAcquireData(typed_data, &typ, &bytes, &bdlen);
605 }
606
607 // Grab the handles if there are any.
James Robinsona6a13fb2015-10-19 15:37:01 -0700608 std::unique_ptr<MojoHandle[]> mojo_handles;
Zachary Anderson70d85e92014-12-02 21:59:36 -0800609 intptr_t handles_len = 0;
610 if (!Dart_IsNull(handles)) {
611 Dart_ListLength(handles, &handles_len);
612 if (handles_len > 0) {
613 mojo_handles.reset(new MojoHandle[handles_len]);
614 }
615 for (int i = 0; i < handles_len; i++) {
616 Dart_Handle dart_handle = Dart_ListGetAt(handles, i);
617 if (!Dart_IsInteger(dart_handle)) {
618 SetInvalidArgumentReturn(arguments);
619 return;
620 }
621 int64_t mojo_handle = 0;
622 Dart_IntegerToInt64(dart_handle, &mojo_handle);
623 mojo_handles[i] = static_cast<MojoHandle>(mojo_handle);
624 }
625 }
626
627 MojoResult res = MojoWriteMessage(
628 static_cast<MojoHandle>(handle),
629 const_cast<const void*>(bytes),
630 static_cast<uint32_t>(num_bytes),
631 mojo_handles.get(),
632 static_cast<uint32_t>(handles_len),
633 static_cast<MojoWriteMessageFlags>(flags));
634
635 // Release the data.
636 if (!Dart_IsNull(typed_data)) {
637 Dart_TypedDataReleaseData(typed_data);
638 }
639
640 Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
641}
642
643void MojoMessagePipe_Read(Dart_NativeArguments arguments) {
644 int64_t handle = 0;
645 CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
646
647 Dart_Handle typed_data = Dart_GetNativeArgument(arguments, 1);
648 if (!Dart_IsTypedData(typed_data) && !Dart_IsNull(typed_data)) {
649 SetNullReturn(arguments);
650 return;
651 }
652 // When querying the amount of data available to read from the pipe,
653 // null is passed in for typed_data.
654
655 int64_t num_bytes = 0;
656 CHECK_INTEGER_ARGUMENT(arguments, 2, &num_bytes, Null);
657 if ((Dart_IsNull(typed_data) && (num_bytes != 0)) ||
658 (!Dart_IsNull(typed_data) && (num_bytes <= 0))) {
659 SetNullReturn(arguments);
660 return;
661 }
662
663 Dart_Handle handles = Dart_GetNativeArgument(arguments, 3);
664 if (!Dart_IsList(handles) && !Dart_IsNull(handles)) {
665 SetNullReturn(arguments);
666 return;
667 }
668
669 int64_t flags = 0;
670 CHECK_INTEGER_ARGUMENT(arguments, 4, &flags, Null);
671
672 // Grab the data if there is any.
673 Dart_TypedData_Type typ;
674 void* bytes = nullptr;
675 intptr_t byte_data_len = 0;
676 if (!Dart_IsNull(typed_data)) {
677 Dart_TypedDataAcquireData(typed_data, &typ, &bytes, &byte_data_len);
678 }
679 uint32_t blen = static_cast<uint32_t>(num_bytes);
680
681 // Grab the handles if there are any.
James Robinsona6a13fb2015-10-19 15:37:01 -0700682 std::unique_ptr<MojoHandle[]> mojo_handles;
Zachary Anderson70d85e92014-12-02 21:59:36 -0800683 intptr_t handles_len = 0;
684 if (!Dart_IsNull(handles)) {
685 Dart_ListLength(handles, &handles_len);
686 mojo_handles.reset(new MojoHandle[handles_len]);
687 }
688 uint32_t hlen = static_cast<uint32_t>(handles_len);
689
690 MojoResult res = MojoReadMessage(
691 static_cast<MojoHandle>(handle),
692 bytes,
693 &blen,
694 mojo_handles.get(),
695 &hlen,
696 static_cast<MojoReadMessageFlags>(flags));
697
698 // Release the data.
699 if (!Dart_IsNull(typed_data)) {
700 Dart_TypedDataReleaseData(typed_data);
701 }
702
703 if (!Dart_IsNull(handles)) {
704 for (int i = 0; i < handles_len; i++) {
705 Dart_ListSetAt(handles, i, Dart_NewInteger(mojo_handles[i]));
706 }
707 }
708
709 Dart_Handle list = Dart_NewList(3);
710 Dart_ListSetAt(list, 0, Dart_NewInteger(res));
711 Dart_ListSetAt(list, 1, Dart_NewInteger(blen));
712 Dart_ListSetAt(list, 2, Dart_NewInteger(hlen));
713 Dart_SetReturnValue(arguments, list);
714}
715
Zachary Anderson321bf1a2015-11-06 15:59:07 -0800716void ByteArrayFinalizer(void* isolate_callback_data,
717 Dart_WeakPersistentHandle handle,
718 void* peer) {
719 uint8_t* byte_array = reinterpret_cast<uint8_t*>(peer);
720 delete[] byte_array;
721}
722
723void HandleArrayFinalizer(void* isolate_callback_data,
724 Dart_WeakPersistentHandle handle,
725 void* peer) {
726 uint32_t* handle_array = reinterpret_cast<uint32_t*>(peer);
727 delete[] handle_array;
728}
729
730void MojoMessagePipe_QueryAndRead(Dart_NativeArguments arguments) {
731 Dart_Handle err;
732 int64_t dart_handle;
733 int64_t flags = 0;
734 CHECK_INTEGER_ARGUMENT(arguments, 0, &dart_handle, Null);
735 CHECK_INTEGER_ARGUMENT(arguments, 1, &flags, Null);
736 Dart_Handle result = Dart_GetNativeArgument(arguments, 2);
737
738 Dart_Handle data = Dart_ListGetAt(result, 1);
739 Dart_Handle handles = Dart_ListGetAt(result, 2);
740
741 // Query the number of bytes and handles available.
742 uint32_t blen = 0;
743 uint32_t hlen = 0;
744 MojoResult res =
745 MojoReadMessage(static_cast<MojoHandle>(dart_handle), nullptr, &blen,
746 nullptr, &hlen, static_cast<MojoReadMessageFlags>(flags));
747
748 if ((res != MOJO_RESULT_OK) && (res != MOJO_RESULT_RESOURCE_EXHAUSTED)) {
749 Dart_ListSetAt(result, 0, Dart_NewInteger(res));
750 Dart_ListSetAt(result, 1, data);
751 Dart_ListSetAt(result, 2, handles);
752 Dart_ListSetAt(result, 3, Dart_NewInteger(0));
753 Dart_ListSetAt(result, 4, Dart_NewInteger(0));
754 return;
755 }
756
757 Dart_TypedData_Type typ;
758 void* bytes = nullptr;
759 intptr_t bytes_len = 0;
760 if ((blen > 0) && Dart_IsNull(data)) {
761 uint8_t* new_byte_data = new uint8_t[blen];
762 data = Dart_NewExternalTypedData(Dart_TypedData_kByteData, new_byte_data,
763 blen);
764 MOJO_DCHECK(!Dart_IsError(data));
765 Dart_NewWeakPersistentHandle(data, new_byte_data, blen, ByteArrayFinalizer);
766 } else if (blen > 0) {
767 err = Dart_TypedDataAcquireData(data, &typ, &bytes, &bytes_len);
768 MOJO_DCHECK(!Dart_IsError(err));
769 err = Dart_TypedDataReleaseData(data);
770 MOJO_DCHECK(!Dart_IsError(err));
771 if (static_cast<uintptr_t>(bytes_len) < blen) {
772 uint8_t* new_byte_data = new uint8_t[blen];
773 data = Dart_NewExternalTypedData(Dart_TypedData_kByteData, new_byte_data,
774 blen);
775 MOJO_DCHECK(!Dart_IsError(data));
776 Dart_NewWeakPersistentHandle(data, new_byte_data, blen,
777 ByteArrayFinalizer);
778 }
779 }
780
781 void* handle_bytes = nullptr;
782 intptr_t handles_len = 0;
783 if ((hlen > 0) && Dart_IsNull(handles)) {
784 uint32_t* new_handle_data = new uint32_t[hlen];
785 handles = Dart_NewExternalTypedData(Dart_TypedData_kUint32, new_handle_data,
786 hlen);
787 MOJO_DCHECK(!Dart_IsError(handles));
788 Dart_NewWeakPersistentHandle(handles, new_handle_data,
789 hlen * sizeof(uint32_t), HandleArrayFinalizer);
790 } else if (hlen > 0) {
791 err = Dart_TypedDataAcquireData(handles, &typ, &handle_bytes, &handles_len);
792 MOJO_DCHECK(!Dart_IsError(err));
793 err = Dart_TypedDataReleaseData(handles);
794 MOJO_DCHECK(!Dart_IsError(err));
795 if (static_cast<uintptr_t>(handles_len) < hlen) {
796 uint32_t* new_handle_data = new uint32_t[hlen];
797 handles = Dart_NewExternalTypedData(Dart_TypedData_kUint32,
798 new_handle_data, hlen);
799 MOJO_DCHECK(!Dart_IsError(handles));
800 Dart_NewWeakPersistentHandle(handles, new_handle_data,
801 hlen * sizeof(uint32_t),
802 HandleArrayFinalizer);
803 }
804 }
805
806 if (blen > 0) {
807 err = Dart_TypedDataAcquireData(data, &typ, &bytes, &bytes_len);
808 MOJO_DCHECK(!Dart_IsError(err));
809 }
810
811 if (hlen > 0) {
812 err = Dart_TypedDataAcquireData(handles, &typ, &handle_bytes, &handles_len);
813 MOJO_DCHECK(!Dart_IsError(err));
814 }
815
816 res = MojoReadMessage(static_cast<MojoHandle>(dart_handle), bytes, &blen,
817 reinterpret_cast<MojoHandle*>(handle_bytes), &hlen,
818 static_cast<MojoReadMessageFlags>(flags));
819
820 if (blen > 0) {
821 err = Dart_TypedDataReleaseData(data);
822 MOJO_DCHECK(!Dart_IsError(err));
823 }
824
825 if (hlen > 0) {
826 err = Dart_TypedDataReleaseData(handles);
827 MOJO_DCHECK(!Dart_IsError(err));
828 }
829
830 Dart_ListSetAt(result, 0, Dart_NewInteger(res));
831 Dart_ListSetAt(result, 1, data);
832 Dart_ListSetAt(result, 2, handles);
833 Dart_ListSetAt(result, 3, Dart_NewInteger(blen));
834 Dart_ListSetAt(result, 4, Dart_NewInteger(hlen));
835}
836
Zachary Andersone54a9192015-10-07 09:27:42 -0700837struct MojoWaitManyState {
Jason Simmons9aaee9d2015-10-09 17:19:03 -0700838 MojoWaitManyState() {}
839
Zachary Andersone54a9192015-10-07 09:27:42 -0700840 std::vector<uint32_t> handles;
841 std::vector<uint32_t> signals;
842 std::vector<uint32_t> out_index;
843 std::vector<MojoHandleSignalsState> out_signals;
Jason Simmons9aaee9d2015-10-09 17:19:03 -0700844
845 static MojoWaitManyState* GetInstance();
846
847 private:
Zachary Anderson241ff8a2015-10-27 15:06:13 -0700848 MOJO_DISALLOW_COPY_AND_ASSIGN(MojoWaitManyState);
Zachary Andersone54a9192015-10-07 09:27:42 -0700849};
850
851// This global is safe because it is only accessed by the single handle watcher
852// isolate. If multiple handle watcher isolates are ever needed, it will need
853// to be replicated.
Jason Simmons9aaee9d2015-10-09 17:19:03 -0700854MojoWaitManyState* MojoWaitManyState::GetInstance() {
855 static MojoWaitManyState* state = new MojoWaitManyState;
856 return state;
857}
Zachary Andersone54a9192015-10-07 09:27:42 -0700858
859void MojoHandleWatcher_GrowStateArrays(Dart_NativeArguments arguments) {
860 int64_t new_length;
861 CHECK_INTEGER_ARGUMENT(arguments, 0, &new_length, InvalidArgument);
862
Jason Simmons9aaee9d2015-10-09 17:19:03 -0700863 MojoWaitManyState& handle_watcher_wait_state =
864 *MojoWaitManyState::GetInstance();
865
Zachary Andersone54a9192015-10-07 09:27:42 -0700866 handle_watcher_wait_state.handles.resize(new_length);
867 handle_watcher_wait_state.signals.resize(new_length);
868 handle_watcher_wait_state.out_index.resize(1);
869 handle_watcher_wait_state.out_signals.resize(new_length);
870
871 Dart_Handle dart_handles = Dart_NewExternalTypedData(
872 Dart_TypedData_kUint32, handle_watcher_wait_state.handles.data(),
873 handle_watcher_wait_state.handles.size());
874 if (Dart_IsError(dart_handles)) {
875 Dart_PropagateError(dart_handles);
876 }
877 if (Dart_IsNull(dart_handles)) {
878 SetNullReturn(arguments);
879 return;
880 }
881
882 Dart_Handle dart_signals = Dart_NewExternalTypedData(
883 Dart_TypedData_kUint32, handle_watcher_wait_state.signals.data(),
884 handle_watcher_wait_state.signals.size());
885 if (Dart_IsError(dart_signals)) {
886 Dart_PropagateError(dart_signals);
887 }
888 if (Dart_IsNull(dart_signals)) {
889 SetNullReturn(arguments);
890 return;
891 }
892
893 Dart_Handle dart_out_index = Dart_NewExternalTypedData(
894 Dart_TypedData_kUint32, handle_watcher_wait_state.out_index.data(),
895 handle_watcher_wait_state.out_index.size());
896 if (Dart_IsError(dart_out_index)) {
897 Dart_PropagateError(dart_out_index);
898 }
899 if (Dart_IsNull(dart_out_index)) {
900 SetNullReturn(arguments);
901 return;
902 }
903
904 Dart_Handle dart_out_signals = Dart_NewExternalTypedData(
905 Dart_TypedData_kUint64, handle_watcher_wait_state.out_signals.data(),
906 handle_watcher_wait_state.out_signals.size());
907 if (Dart_IsError(dart_out_signals)) {
908 Dart_PropagateError(dart_out_signals);
909 }
910 if (Dart_IsNull(dart_out_signals)) {
911 SetNullReturn(arguments);
912 return;
913 }
914
915 Dart_Handle list = Dart_NewList(4);
916 Dart_ListSetAt(list, 0, dart_handles);
917 Dart_ListSetAt(list, 1, dart_signals);
918 Dart_ListSetAt(list, 2, dart_out_index);
919 Dart_ListSetAt(list, 3, dart_out_signals);
920 Dart_SetReturnValue(arguments, list);
921}
922
923void MojoHandleWatcher_WaitMany(Dart_NativeArguments arguments) {
924 int64_t handles_len = 0;
925 int64_t deadline = 0;
926 CHECK_INTEGER_ARGUMENT(arguments, 0, &handles_len, InvalidArgument);
927 CHECK_INTEGER_ARGUMENT(arguments, 1, &deadline, InvalidArgument);
928
Jason Simmons9aaee9d2015-10-09 17:19:03 -0700929 MojoWaitManyState& handle_watcher_wait_state =
930 *MojoWaitManyState::GetInstance();
931
Zachary Andersone54a9192015-10-07 09:27:42 -0700932 uint32_t* handles = handle_watcher_wait_state.handles.data();
933 uint32_t* signals = handle_watcher_wait_state.signals.data();
934 uint32_t* out_index = handle_watcher_wait_state.out_index.data();
935 MojoHandleSignalsState* out_signals =
936 handle_watcher_wait_state.out_signals.data();
937
John McCutchane4ac2362015-11-12 11:33:57 -0800938 Dart_ThreadDisableProfiling();
939
Zachary Andersone54a9192015-10-07 09:27:42 -0700940 MojoResult mojo_result = MojoWaitMany(handles, signals, handles_len, deadline,
941 out_index, out_signals);
John McCutchane4ac2362015-11-12 11:33:57 -0800942 Dart_ThreadEnableProfiling();
Zachary Andersone54a9192015-10-07 09:27:42 -0700943
944 Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(mojo_result));
945}
946
Zachary Anderson70d85e92014-12-02 21:59:36 -0800947struct ControlData {
948 int64_t handle;
949 Dart_Port port;
950 int64_t data;
951};
952
953void MojoHandleWatcher_SendControlData(Dart_NativeArguments arguments) {
954 int64_t control_handle = 0;
955 int64_t client_handle = 0;
956 CHECK_INTEGER_ARGUMENT(arguments, 0, &control_handle, InvalidArgument);
957 CHECK_INTEGER_ARGUMENT(arguments, 1, &client_handle, InvalidArgument);
958
959 Dart_Handle send_port_handle = Dart_GetNativeArgument(arguments, 2);
John McCutchan7436c6d2015-04-06 14:28:06 -0700960 Dart_Port send_port_id = ILLEGAL_PORT;
Zachary Anderson70d85e92014-12-02 21:59:36 -0800961 if (!Dart_IsNull(send_port_handle)) {
962 Dart_Handle result = Dart_SendPortGetId(send_port_handle, &send_port_id);
963 if (Dart_IsError(result)) {
964 SetInvalidArgumentReturn(arguments);
965 return;
966 }
967 }
968
969 int64_t data = 0;
970 CHECK_INTEGER_ARGUMENT(arguments, 3, &data, InvalidArgument);
971
972 ControlData cd;
973 cd.handle = client_handle;
974 cd.port = send_port_id;
975 cd.data = data;
976 const void* bytes = reinterpret_cast<const void*>(&cd);
977 MojoResult res = MojoWriteMessage(
978 control_handle, bytes, sizeof(cd), nullptr, 0, 0);
979 Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
980}
981
982void MojoHandleWatcher_RecvControlData(Dart_NativeArguments arguments) {
983 int64_t control_handle = 0;
984 CHECK_INTEGER_ARGUMENT(arguments, 0, &control_handle, Null);
985
986 ControlData cd;
987 void* bytes = reinterpret_cast<void*>(&cd);
988 uint32_t num_bytes = sizeof(cd);
989 uint32_t num_handles = 0;
990 MojoResult res = MojoReadMessage(
991 control_handle, bytes, &num_bytes, nullptr, &num_handles, 0);
992 if (res != MOJO_RESULT_OK) {
993 SetNullReturn(arguments);
994 return;
995 }
996
997 Dart_Handle list = Dart_NewList(3);
998 Dart_ListSetAt(list, 0, Dart_NewInteger(cd.handle));
John McCutchan7436c6d2015-04-06 14:28:06 -0700999 if (cd.port != ILLEGAL_PORT) {
1000 Dart_ListSetAt(list, 1, Dart_NewSendPort(cd.port));
1001 }
Zachary Anderson70d85e92014-12-02 21:59:36 -08001002 Dart_ListSetAt(list, 2, Dart_NewInteger(cd.data));
1003 Dart_SetReturnValue(arguments, list);
1004}
1005
1006static int64_t mojo_control_handle = MOJO_HANDLE_INVALID;
1007void MojoHandleWatcher_SetControlHandle(Dart_NativeArguments arguments) {
1008 int64_t control_handle;
1009 CHECK_INTEGER_ARGUMENT(arguments, 0, &control_handle, InvalidArgument);
Zachary Anderson2a58cd82014-12-04 14:01:33 -08001010 mojo_control_handle = control_handle;
Zachary Anderson70d85e92014-12-02 21:59:36 -08001011 Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(MOJO_RESULT_OK));
1012}
1013
1014void MojoHandleWatcher_GetControlHandle(Dart_NativeArguments arguments) {
1015 Dart_SetIntegerReturnValue(arguments, mojo_control_handle);
1016}
1017
1018} // namespace dart
1019} // namespace mojo