OLD | NEW |
| (Empty) |
1 // Copyright 2015 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 package native_cgo | |
6 | |
7 //#include <mojo/result.h> | |
8 //#include <mojo/system/buffer.h> | |
9 //#include <mojo/system/data_pipe.h> | |
10 //#include <mojo/system/handle.h> | |
11 //#include <mojo/system/message_pipe.h> | |
12 //#include <mojo/system/time.h> | |
13 //#include <mojo/system/wait.h> | |
14 // | |
15 // // These functions are used to 8-byte align C structs. | |
16 // MojoResult CreateSharedBuffer(struct MojoCreateSharedBufferOptions* options, | |
17 // uint64_t num_bytes, MojoHandle* handle) { | |
18 // struct MojoCreateSharedBufferOptions aligned_options; | |
19 // if (options != NULL) { | |
20 // aligned_options = *options; | |
21 // return MojoCreateSharedBuffer(&aligned_options, num_bytes, handle); | |
22 // } else { | |
23 // return MojoCreateSharedBuffer(NULL, num_bytes, handle); | |
24 // } | |
25 // } | |
26 // | |
27 // MojoResult DuplicateBufferHandle(MojoHandle handle, | |
28 // struct MojoDuplicateBufferHandleOptions* options, MojoHandle* duplicate)
{ | |
29 // struct MojoDuplicateBufferHandleOptions aligned_options; | |
30 // if (options != NULL) { | |
31 // aligned_options = *options; | |
32 // return MojoDuplicateBufferHandle(handle, &aligned_options, duplicate); | |
33 // } else { | |
34 // return MojoDuplicateBufferHandle(handle, NULL, duplicate); | |
35 // } | |
36 // } | |
37 // | |
38 // MojoResult CreateDataPipe(struct MojoCreateDataPipeOptions* options, | |
39 // MojoHandle* producer, MojoHandle* consumer) { | |
40 // struct MojoCreateDataPipeOptions aligned_options; | |
41 // if (options != NULL) { | |
42 // aligned_options = *options; | |
43 // return MojoCreateDataPipe(&aligned_options, producer, consumer); | |
44 // } else { | |
45 // return MojoCreateDataPipe(NULL, producer, consumer); | |
46 // } | |
47 // } | |
48 // | |
49 // MojoResult CreateMessagePipe(struct MojoCreateMessagePipeOptions* options, | |
50 // MojoHandle* handle0, MojoHandle* handle1) { | |
51 // struct MojoCreateMessagePipeOptions aligned_options = *options; | |
52 // if (options != NULL) { | |
53 // aligned_options = *options; | |
54 // return MojoCreateMessagePipe(&aligned_options, handle0, handle1); | |
55 // } else { | |
56 // return MojoCreateMessagePipe(NULL, handle0, handle1); | |
57 // } | |
58 // } | |
59 // | |
60 import "C" | |
61 import ( | |
62 "unsafe" | |
63 ) | |
64 | |
65 // CGoSystem provides an implementation of the system.MojoSystem interface based
on CGO | |
66 type CGoSystem struct{} | |
67 | |
68 func (c *CGoSystem) CreateSharedBuffer(flags uint32, numBytes uint64) (uint32, u
int32) { | |
69 var opts *C.struct_MojoCreateSharedBufferOptions | |
70 opts = &C.struct_MojoCreateSharedBufferOptions{ | |
71 C.uint32_t(unsafe.Sizeof(*opts)), | |
72 C.MojoCreateSharedBufferOptionsFlags(flags), | |
73 } | |
74 var cHandle C.MojoHandle | |
75 r := C.CreateSharedBuffer(opts, C.uint64_t(numBytes), &cHandle) | |
76 return uint32(r), uint32(cHandle) | |
77 } | |
78 | |
79 func (c *CGoSystem) DuplicateBufferHandle(handle uint32, flags uint32) (uint32,
uint32) { | |
80 var opts *C.struct_MojoDuplicateBufferHandleOptions | |
81 opts = &C.struct_MojoDuplicateBufferHandleOptions{ | |
82 C.uint32_t(unsafe.Sizeof(*opts)), | |
83 C.MojoDuplicateBufferHandleOptionsFlags(flags), | |
84 } | |
85 var cDuplicateHandle C.MojoHandle | |
86 r := C.DuplicateBufferHandle(C.MojoHandle(handle), opts, &cDuplicateHand
le) | |
87 return uint32(r), uint32(cDuplicateHandle) | |
88 } | |
89 | |
90 func (c *CGoSystem) MapBuffer(handle uint32, offset, numBytes uint64, flags uint
32) (result uint32, buf []byte) { | |
91 var bufPtr unsafe.Pointer | |
92 r := C.MojoMapBuffer(C.MojoHandle(handle), C.uint64_t(offset), C.uint64_
t(numBytes), &bufPtr, C.MojoMapBufferFlags(flags)) | |
93 if r != C.MOJO_RESULT_OK { | |
94 return uint32(r), nil | |
95 } | |
96 return uint32(r), unsafeByteSlice(bufPtr, int(numBytes)) | |
97 } | |
98 | |
99 func (c *CGoSystem) GetBufferInformation(handle uint32) (result uint32, flags ui
nt32, numBytes uint64) { | |
100 var info *C.struct_MojoBufferInformation | |
101 info = &C.struct_MojoBufferInformation{} | |
102 r := C.MojoGetBufferInformation(C.MojoHandle(handle), info, C.uint32_t(u
nsafe.Sizeof(*info))) | |
103 | |
104 return uint32(r), uint32(info.flags), uint64(info.num_bytes) | |
105 } | |
106 | |
107 func (c *CGoSystem) UnmapBuffer(buf []byte) (result uint32) { | |
108 return uint32(C.MojoUnmapBuffer(unsafe.Pointer(&buf[0]))) | |
109 } | |
110 | |
111 func createDataPipeWithCOptions(opts *C.struct_MojoCreateDataPipeOptions) (resul
t uint32, producerHandle, consumerHandle uint32) { | |
112 var cProducerHandle, cConsumerHandle C.MojoHandle | |
113 r := C.CreateDataPipe(opts, &cProducerHandle, &cConsumerHandle) | |
114 return uint32(r), uint32(cProducerHandle), uint32(cConsumerHandle) | |
115 } | |
116 | |
117 func (c *CGoSystem) CreateDataPipe(flags, elementNumBytes, capacityNumBytes uint
32) (result uint32, producerHandle, consumerHandle uint32) { | |
118 var opts *C.struct_MojoCreateDataPipeOptions | |
119 opts = &C.struct_MojoCreateDataPipeOptions{ | |
120 C.uint32_t(unsafe.Sizeof(*opts)), | |
121 C.MojoCreateDataPipeOptionsFlags(flags), | |
122 C.uint32_t(elementNumBytes), | |
123 C.uint32_t(capacityNumBytes), | |
124 } | |
125 return createDataPipeWithCOptions(opts) | |
126 } | |
127 | |
128 func (c *CGoSystem) CreateDataPipeWithDefaultOptions() (result uint32, producerH
andle, consumerHandle uint32) { | |
129 // A nil options pointer in the C interface means use the default values
. | |
130 return createDataPipeWithCOptions(nil) | |
131 } | |
132 | |
133 func (c *CGoSystem) WriteData(producerHandle uint32, buf []byte, flags uint32) (
result uint32, bytesWritten uint32) { | |
134 numBytes := C.uint32_t(len(buf)) | |
135 r := C.MojoWriteData(C.MojoHandle(producerHandle), unsafe.Pointer(&buf[0
]), &numBytes, C.MojoWriteDataFlags(flags)) | |
136 return uint32(r), uint32(numBytes) | |
137 } | |
138 | |
139 func (c *CGoSystem) BeginWriteData(producerHandle uint32, flags uint32) (result
uint32, buf []byte) { | |
140 var buffer unsafe.Pointer | |
141 var bufferNumBytes C.uint32_t | |
142 r := C.MojoBeginWriteData(C.MojoHandle(producerHandle), &buffer, &buffer
NumBytes, C.MojoWriteDataFlags(flags)) | |
143 if r != C.MOJO_RESULT_OK { | |
144 return uint32(r), nil | |
145 } | |
146 return uint32(r), unsafeByteSlice(buffer, int(bufferNumBytes)) | |
147 } | |
148 | |
149 func (c *CGoSystem) EndWriteData(producerHandle uint32, numBytesWritten uint32)
(result uint32) { | |
150 return uint32(C.MojoEndWriteData(C.MojoHandle(producerHandle), C.uint32_
t(numBytesWritten))) | |
151 } | |
152 | |
153 func (c *CGoSystem) ReadData(consumerHandle uint32, flags uint32) (result uint32
, buf []byte) { | |
154 var numBytes C.uint32_t | |
155 if r := C.MojoReadData(C.MojoHandle(consumerHandle), nil, &numBytes, C.M
OJO_READ_DATA_FLAG_QUERY); r != C.MOJO_RESULT_OK { | |
156 return uint32(r), nil | |
157 } | |
158 if numBytes == 0 { | |
159 return uint32(C.MOJO_RESULT_OK), nil | |
160 } | |
161 buf = make([]byte, int(numBytes)) | |
162 r := C.MojoReadData(C.MojoHandle(consumerHandle), unsafe.Pointer(&buf[0]
), &numBytes, C.MojoReadDataFlags(flags)) | |
163 buf = buf[0:int(numBytes)] | |
164 return uint32(r), buf | |
165 } | |
166 | |
167 func (c *CGoSystem) BeginReadData(consumerHandle uint32, flags uint32) (result u
int32, buf []byte) { | |
168 var buffer unsafe.Pointer | |
169 var bufferNumBytes C.uint32_t | |
170 r := C.MojoBeginReadData(C.MojoHandle(consumerHandle), &buffer, &bufferN
umBytes, C.MojoReadDataFlags(flags)) | |
171 if r != C.MOJO_RESULT_OK { | |
172 return uint32(r), nil | |
173 } | |
174 return uint32(r), unsafeByteSlice(buffer, int(bufferNumBytes)) | |
175 } | |
176 | |
177 func (c *CGoSystem) EndReadData(consumerHandle uint32, numBytesRead uint32) (res
ult uint32) { | |
178 return uint32(C.MojoEndReadData(C.MojoHandle(consumerHandle), C.uint32_t
(numBytesRead))) | |
179 } | |
180 | |
181 func (c *CGoSystem) GetTimeTicksNow() (timestamp uint64) { | |
182 return uint64(C.MojoGetTimeTicksNow()) | |
183 } | |
184 | |
185 func (c *CGoSystem) Close(handle uint32) (result uint32) { | |
186 return uint32(C.MojoClose(C.MojoHandle(handle))) | |
187 } | |
188 | |
189 func (c *CGoSystem) Wait(handle uint32, signals uint32, deadline uint64) (result
uint32, satisfiedSignals, satisfiableSignals uint32) { | |
190 var cState C.struct_MojoHandleSignalsState | |
191 r := C.MojoWait(C.MojoHandle(handle), C.MojoHandleSignals(signals), C.Mo
joDeadline(deadline), &cState) | |
192 return uint32(r), uint32(cState.satisfied_signals), uint32(cState.satisf
iable_signals) | |
193 } | |
194 | |
195 func (c *CGoSystem) WaitMany(handles []uint32, signals []uint32, deadline uint64
) (uint32, int, []uint32, []uint32) { | |
196 if len(handles) == 0 { | |
197 r := C.MojoWaitMany(nil, nil, 0, C.MojoDeadline(deadline), nil,
nil) | |
198 return uint32(r), -1, nil, nil | |
199 } | |
200 if len(handles) != len(signals) { | |
201 panic("number of handles and signals must match") | |
202 } | |
203 index := ^C.uint32_t(0) // -1 | |
204 cHandles := (*C.MojoHandle)(unsafe.Pointer(&handles[0])) | |
205 cSignals := (*C.MojoHandleSignals)(unsafe.Pointer(&signals[0])) | |
206 cStates := make([]C.struct_MojoHandleSignalsState, len(handles)) | |
207 r := C.MojoWaitMany(cHandles, cSignals, C.uint32_t(len(handles)), C.Mojo
Deadline(deadline), &index, &cStates[0]) | |
208 var satisfied, satisfiable []uint32 | |
209 if r != C.MOJO_RESULT_INVALID_ARGUMENT && r != C.MOJO_RESULT_RESOURCE_EX
HAUSTED { | |
210 satisfied = make([]uint32, len(handles)) | |
211 satisfiable = make([]uint32, len(handles)) | |
212 for i := 0; i < len(handles); i++ { | |
213 satisfied[i] = uint32(cStates[i].satisfied_signals) | |
214 satisfiable[i] = uint32(cStates[i].satisfiable_signals) | |
215 } | |
216 } | |
217 return uint32(r), int(int32(index)), satisfied, satisfiable | |
218 } | |
219 | |
220 func (c *CGoSystem) CreateMessagePipe(flags uint32) (uint32, uint32, uint32) { | |
221 var handle0, handle1 C.MojoHandle | |
222 var opts *C.struct_MojoCreateMessagePipeOptions | |
223 opts = &C.struct_MojoCreateMessagePipeOptions{ | |
224 C.uint32_t(unsafe.Sizeof(*opts)), | |
225 C.MojoCreateMessagePipeOptionsFlags(flags), | |
226 } | |
227 r := C.CreateMessagePipe(opts, &handle0, &handle1) | |
228 return uint32(r), uint32(handle0), uint32(handle1) | |
229 } | |
230 | |
231 func (c *CGoSystem) WriteMessage(handle uint32, bytes []byte, handles []uint32,
flags uint32) (result uint32) { | |
232 var bytesPtr unsafe.Pointer | |
233 if len(bytes) != 0 { | |
234 bytesPtr = unsafe.Pointer(&bytes[0]) | |
235 } | |
236 var handlesPtr *C.MojoHandle | |
237 if len(handles) != 0 { | |
238 handlesPtr = (*C.MojoHandle)(unsafe.Pointer(&handles[0])) | |
239 } | |
240 return uint32(C.MojoWriteMessage(C.MojoHandle(handle), bytesPtr, C.uint3
2_t(len(bytes)), handlesPtr, C.uint32_t(len(handles)), C.MojoWriteMessageFlags(f
lags))) | |
241 } | |
242 | |
243 func (c *CGoSystem) ReadMessage(handle uint32, flags uint32) (result uint32, buf
[]byte, handles []uint32) { | |
244 var numBytes, numHandles C.uint32_t | |
245 cHandle := C.MojoHandle(handle) | |
246 cFlags := C.MojoReadMessageFlags(flags) | |
247 if r := C.MojoReadMessage(cHandle, nil, &numBytes, nil, &numHandles, cFl
ags); r != C.MOJO_RESULT_RESOURCE_EXHAUSTED { | |
248 return uint32(r), nil, nil | |
249 } | |
250 var bufPtr unsafe.Pointer | |
251 if numBytes != 0 { | |
252 buf = make([]byte, int(numBytes)) | |
253 bufPtr = unsafe.Pointer(&buf[0]) | |
254 } | |
255 var handlesPtr *C.MojoHandle | |
256 if numHandles != 0 { | |
257 handles = make([]uint32, int(numHandles)) | |
258 handlesPtr = (*C.MojoHandle)(unsafe.Pointer(&handles[0])) | |
259 } | |
260 r := C.MojoReadMessage(cHandle, bufPtr, &numBytes, handlesPtr, &numHandl
es, cFlags) | |
261 return uint32(r), buf, handles | |
262 } | |
263 | |
264 func unsafeByteSlice(ptr unsafe.Pointer, length int) []byte { | |
265 return (*[^uint32(0) / 8]byte)(ptr)[:length:length] | |
266 } | |
OLD | NEW |