| 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 |