Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(262)

Side by Side Diff: mojo/public/python/mojo_system.pyx

Issue 2250183003: Make the fuchsia mojo/public repo the source of truth. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # 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 # distutils language = c++
6
7 cimport c_core
8 cimport c_export # needed so the init function gets exported
9 cimport c_thunks
10
11
12 from cpython.buffer cimport PyBUF_CONTIG
13 from cpython.buffer cimport PyBUF_CONTIG_RO
14 from cpython.buffer cimport Py_buffer
15 from cpython.buffer cimport PyBuffer_FillInfo
16 from cpython.buffer cimport PyBuffer_Release
17 from cpython.buffer cimport PyObject_GetBuffer
18 from cpython.mem cimport PyMem_Malloc, PyMem_Free
19 from cpython.object cimport Py_EQ, Py_NE
20 from libc.stdint cimport int32_t, int64_t, uint32_t, uint64_t, uintptr_t
21
22 import weakref
23 import threading
24
25 import mojo_system_impl
26
27 def SetSystemThunks(system_thunks_as_object):
28 """Bind the basic Mojo Core functions.
29
30 This should only be used by the embedder.
31 """
32 cdef const c_thunks.MojoSystemThunks* system_thunks = (
33 <const c_thunks.MojoSystemThunks*><uintptr_t>system_thunks_as_object)
34 c_thunks.MojoSetSystemThunks(system_thunks)
35
36 HANDLE_INVALID = c_core.MOJO_HANDLE_INVALID
37 # TODO(vtl): Find a way of supporting the new, more flexible/extensible
38 # MojoResult (see mojo/public/c/include/mojo/result.h).
39 RESULT_OK = c_core.MOJO_RESULT_OK
40 RESULT_CANCELLED = c_core.MOJO_RESULT_CANCELLED
41 RESULT_UNKNOWN = c_core.MOJO_RESULT_UNKNOWN
42 RESULT_INVALID_ARGUMENT = c_core.MOJO_RESULT_INVALID_ARGUMENT
43 RESULT_DEADLINE_EXCEEDED = c_core.MOJO_RESULT_DEADLINE_EXCEEDED
44 RESULT_NOT_FOUND = c_core.MOJO_RESULT_NOT_FOUND
45 RESULT_ALREADY_EXISTS = c_core.MOJO_RESULT_ALREADY_EXISTS
46 RESULT_PERMISSION_DENIED = c_core.MOJO_RESULT_PERMISSION_DENIED
47 RESULT_RESOURCE_EXHAUSTED = c_core.MOJO_RESULT_RESOURCE_EXHAUSTED
48 RESULT_FAILED_PRECONDITION = c_core.MOJO_RESULT_FAILED_PRECONDITION
49 RESULT_ABORTED = c_core.MOJO_RESULT_ABORTED
50 RESULT_OUT_OF_RANGE = c_core.MOJO_RESULT_OUT_OF_RANGE
51 RESULT_UNIMPLEMENTED = c_core.MOJO_RESULT_UNIMPLEMENTED
52 RESULT_INTERNAL = c_core.MOJO_RESULT_INTERNAL
53 RESULT_UNAVAILABLE = c_core.MOJO_RESULT_UNAVAILABLE
54 RESULT_DATA_LOSS = c_core.MOJO_RESULT_DATA_LOSS
55 RESULT_BUSY = c_core.MOJO_RESULT_BUSY
56 RESULT_SHOULD_WAIT = c_core.MOJO_RESULT_SHOULD_WAIT
57 DEADLINE_INDEFINITE = c_core.MOJO_DEADLINE_INDEFINITE
58 HANDLE_SIGNAL_NONE = c_core.MOJO_HANDLE_SIGNAL_NONE
59 HANDLE_SIGNAL_READABLE = c_core.MOJO_HANDLE_SIGNAL_READABLE
60 HANDLE_SIGNAL_WRITABLE = c_core.MOJO_HANDLE_SIGNAL_WRITABLE
61 HANDLE_SIGNAL_PEER_CLOSED = c_core.MOJO_HANDLE_SIGNAL_PEER_CLOSED
62 WRITE_MESSAGE_FLAG_NONE = c_core.MOJO_WRITE_MESSAGE_FLAG_NONE
63 READ_MESSAGE_FLAG_NONE = c_core.MOJO_READ_MESSAGE_FLAG_NONE
64 READ_MESSAGE_FLAG_MAY_DISCARD = c_core.MOJO_READ_MESSAGE_FLAG_MAY_DISCARD
65 WRITE_DATA_FLAG_NONE = c_core.MOJO_WRITE_DATA_FLAG_NONE
66 WRITE_DATA_FLAG_ALL_OR_NONE = c_core.MOJO_WRITE_DATA_FLAG_ALL_OR_NONE
67 READ_DATA_FLAG_NONE = c_core.MOJO_READ_DATA_FLAG_NONE
68 READ_DATA_FLAG_ALL_OR_NONE = c_core.MOJO_READ_DATA_FLAG_ALL_OR_NONE
69 READ_DATA_FLAG_DISCARD = c_core.MOJO_READ_DATA_FLAG_DISCARD
70 READ_DATA_FLAG_QUERY = c_core.MOJO_READ_DATA_FLAG_QUERY
71 READ_DATA_FLAG_PEEK = c_core.MOJO_READ_DATA_FLAG_PEEK
72 MAP_BUFFER_FLAG_NONE = c_core.MOJO_MAP_BUFFER_FLAG_NONE
73
74 _WAITMANY_NO_SIGNAL_STATE_ERRORS = [RESULT_INVALID_ARGUMENT,
75 RESULT_RESOURCE_EXHAUSTED]
76
77 def GetTimeTicksNow():
78 """Monotonically increasing tick count representing "right now."
79
80 See mojo/public/c/include/mojo/system/time.h
81 """
82 return c_core.MojoGetTimeTicksNow()
83
84 cdef class _ScopedMemory:
85 """Allocate memory at creation, and deallocate it at destruction."""
86 cdef void* memory
87 def __init__(self, size):
88 self.memory = PyMem_Malloc(size)
89
90 def __dealloc__(self):
91 PyMem_Free(self.memory)
92
93 cdef class _ScopedBuffer:
94 """Retrieve pointer to a buffer a creation, and release it at destruction.
95 """
96 cdef Py_buffer _buf
97 cdef void* buf
98 cdef Py_ssize_t len
99
100 def __init__(self, obj, flags=PyBUF_CONTIG_RO):
101 if obj:
102 if PyObject_GetBuffer(obj, &self._buf, flags) < 0:
103 raise TypeError('Unable to read buffer.')
104 self.buf = self._buf.buf
105 self.len = self._buf.len
106 else:
107 self.buf = NULL
108 self.len = 0
109
110 def __dealloc__(self):
111 if self.buf:
112 PyBuffer_Release(&self._buf)
113
114 def _SliceBuffer(buffer, size):
115 """Slice the given buffer, reducing it to the given size.
116
117 Return None if None is passed in.
118 """
119 if not buffer:
120 return buffer
121 return buffer[:size]
122
123 cdef class _NativeMemoryView(object):
124 """Create a python buffer wrapping the given memory.
125
126 Will also retain the given handle until this object is deallocated.
127 """
128 cdef void* _memory
129 cdef uint32_t _size
130 cdef char _read_only
131 cdef char _wrapped
132 cdef object _handle
133
134 def __init__(self, handle):
135 self._handle = handle
136
137 def __cinit__(self):
138 self._memory = NULL
139 self._size = 0
140 self._read_only = True
141 self._wrapped = False
142
143 cdef Wrap(self,
144 const void* memory,
145 uint32_t size,
146 read_only=True):
147 """Makes this buffer wraps the given memory.
148
149 Must be called before using this buffer, and must only be called once.
150 """
151 assert not self._wrapped
152 self._wrapped = True
153 self._memory = <void*>memory
154 self._size = size
155 self._read_only = read_only
156
157 # buffer interface (PEP 3118)
158 def __getbuffer__(self, Py_buffer *view, int flags):
159 assert self._wrapped
160 if view == NULL:
161 return
162 PyBuffer_FillInfo(view,
163 self,
164 self._memory,
165 self._size,
166 self._read_only,
167 flags)
168
169 def __releasebuffer__(self, Py_buffer *view):
170 assert self._wrapped
171 pass
172
173 # legacy buffer interface
174 def __getsegcount__(self, Py_ssize_t *sizes):
175 assert self._wrapped
176 if sizes != NULL:
177 sizes[0] = self._size
178 return 1
179
180 def __getreadbuffer__(self, Py_ssize_t index, void **data):
181 assert self._wrapped
182 if index != 0:
183 raise SystemError('Index out of bounds: %d' % index)
184 data[0] = self._memory
185 return self._size
186
187 def __getwritebuffer__(self, Py_ssize_t index, void **data):
188 assert self._wrapped
189 if index != 0:
190 raise SystemError('Index out of bounds: %d' % index)
191 if self._read_only:
192 raise TypeError('Buffer is read-only.')
193 data[0] = self._memory
194 return self._size
195
196 class MojoException(Exception):
197 """Exception wrapping a mojo result error code."""
198
199 def __init__(self, mojo_result):
200 self.mojo_result = mojo_result
201
202 def WaitMany(handles_and_signals, deadline):
203 """Waits on a list of handles.
204
205 Args:
206 handles_and_signals: list of tuples of handle and signal.
207
208 See mojo/public/c/include/mojo/system/wait.h
209 """
210 cdef uint32_t length = len(handles_and_signals)
211 cdef uint32_t result_index = <uint32_t>(-1)
212
213 cdef _ScopedMemory handles_alloc = _ScopedMemory(
214 sizeof(c_core.MojoHandle) * length)
215 cdef _ScopedMemory signals_alloc = _ScopedMemory(
216 sizeof(c_core.MojoHandleSignals) * length)
217 cdef _ScopedMemory states_alloc = _ScopedMemory(
218 sizeof(c_core.MojoHandleSignalsState) * length)
219 cdef c_core.MojoHandle* handles = <c_core.MojoHandle*>handles_alloc.memory
220 cdef c_core.MojoHandleSignals* signals = (
221 <c_core.MojoHandleSignals*>signals_alloc.memory)
222 cdef c_core.MojoHandleSignalsState* states = (
223 <c_core.MojoHandleSignalsState*>states_alloc.memory)
224 cdef int index = 0
225 for (h, s) in handles_and_signals:
226 handles[index] = (<Handle?>h)._mojo_handle
227 signals[index] = s
228 index += 1
229 cdef c_core.MojoResult result = c_core.MOJO_RESULT_OK
230 cdef c_core.MojoDeadline cdeadline = deadline
231 with nogil:
232 result = c_core.MojoWaitMany(handles, signals, length, cdeadline,
233 &result_index, states)
234
235 returned_result_index = None
236 if result_index != <uint32_t>(-1):
237 returned_result_index = result_index
238
239 returned_states = None
240 if result not in _WAITMANY_NO_SIGNAL_STATE_ERRORS:
241 returned_states = [(states[i].satisfied_signals,
242 states[i].satisfiable_signals) for i in xrange(length)]
243
244 return (result, returned_result_index, returned_states)
245
246
247 cdef class DataPipeTwoPhaseBuffer(object):
248 """Return value for two phases read and write.
249
250 The buffer field contains the python buffer where data can be read or written.
251 When done with the buffer, the |end| method must be called with the number of
252 bytes read or written.
253 """
254
255 cdef object _buffer
256 cdef Handle _handle
257 cdef char _read
258
259 def __init__(self, handle, buffer, read=True):
260 self._buffer = buffer
261 self._handle = handle
262 self._read = read
263
264 def End(self, num_bytes):
265 self._buffer = None
266 cdef c_core.MojoResult result
267 if self._read:
268 result = c_core.MojoEndReadData(self._handle._mojo_handle, num_bytes)
269 else:
270 result = c_core.MojoEndWriteData(self._handle._mojo_handle, num_bytes)
271 self._handle = None
272 return result
273
274 @property
275 def buffer(self):
276 return self._buffer
277
278 def __dealloc__(self):
279 assert not self._buffer
280
281 cdef class MappedBuffer(object):
282 """Return value for the |map| operation on shared buffer handles.
283
284 The buffer field contains the python buffer where data can be read or written.
285 When done with the buffer, the |unmap| method must be called.
286 """
287
288 cdef object _buffer
289 cdef object _handle
290 cdef object _cleanup
291
292 def __init__(self, handle, buffer, cleanup):
293 self._buffer = buffer
294 self._handle = handle
295 self._cleanup = cleanup
296
297 def UnMap(self):
298 self._buffer = None
299 cdef c_core.MojoResult result = self._cleanup()
300 self._cleanup = None
301 self._handle = None
302 return result
303
304 @property
305 def buffer(self):
306 return self._buffer
307
308 def __dealloc__(self):
309 if self._buffer:
310 self.UnMap()
311
312 cdef class Handle(object):
313 """A mojo object."""
314
315 cdef c_core.MojoHandle _mojo_handle
316
317 def __init__(self, mojo_handle=c_core.MOJO_HANDLE_INVALID):
318 self._mojo_handle = mojo_handle
319
320 def _Invalidate(self):
321 """Invalidate the current handle.
322
323 The close operation is not called. It is the responsability of the caller to
324 ensure that the handle is not leaked.
325 """
326 self._mojo_handle = c_core.MOJO_HANDLE_INVALID
327
328 def __richcmp__(self, other, op):
329 if op != Py_EQ and op != Py_NE:
330 raise TypeError('Handle is not ordered')
331 cdef int equality
332 if type(self) is not type(other):
333 equality = id(self) == id(other)
334 else:
335 equality = (<Handle>self)._mojo_handle == (<Handle>other)._mojo_handle
336 if op == Py_EQ:
337 return equality
338 else:
339 return not equality
340
341 def IsValid(self):
342 """Returns whether this handle is valid."""
343 return self._mojo_handle != c_core.MOJO_HANDLE_INVALID
344
345 def Close(self):
346 """Closes this handle.
347
348 See mojo/public/c/include/mojo/system/handle.h
349 """
350 cdef c_core.MojoResult result = c_core.MOJO_RESULT_OK
351 if self.IsValid():
352 result = c_core.MojoClose(self._mojo_handle)
353 self._Invalidate()
354 return result
355
356 def __dealloc__(self):
357 self.Close()
358
359 def Wait(self, signals, deadline):
360 """Waits on the given handle.
361
362 See mojo/public/c/include/mojo/system/wait.h
363 """
364 cdef c_core.MojoHandle handle = self._mojo_handle
365 cdef c_core.MojoHandleSignals csignals = signals
366 cdef c_core.MojoDeadline cdeadline = deadline
367 cdef c_core.MojoHandleSignalsState signal_states
368 cdef c_core.MojoResult result
369 with nogil:
370 result = c_core.MojoWait(handle, csignals, cdeadline, &signal_states)
371
372 returned_states = None
373 if result not in _WAITMANY_NO_SIGNAL_STATE_ERRORS:
374 returned_states = (signal_states.satisfied_signals,
375 signal_states.satisfiable_signals)
376
377 return (result, returned_states)
378
379 def AsyncWait(self, signals, deadline, callback):
380 cdef c_core.MojoHandle handle = self._mojo_handle
381 cdef c_core.MojoHandleSignals csignals = signals
382 cdef c_core.MojoDeadline cdeadline = deadline
383 wait_id = _ASYNC_WAITER.AsyncWait(
384 handle,
385 csignals,
386 cdeadline,
387 callback)
388 def cancel():
389 _ASYNC_WAITER.CancelWait(wait_id)
390 return cancel
391
392 def WriteMessage(self,
393 buffer=None,
394 handles=None,
395 flags=WRITE_MESSAGE_FLAG_NONE):
396 """Writes a message to the message pipe.
397
398 This method can only be used on a handle obtained from |MessagePipe()|.
399
400 See mojo/public/c/include/mojo/system/message_pipe.h
401 """
402 cdef _ScopedBuffer buffer_as_buffer = _ScopedBuffer(buffer)
403 cdef uint32_t input_buffer_length = buffer_as_buffer.len
404 cdef c_core.MojoHandle* input_handles = NULL
405 cdef uint32_t input_handles_length = 0
406 cdef _ScopedMemory handles_alloc = None
407 if handles:
408 input_handles_length = len(handles)
409 handles_alloc = _ScopedMemory(sizeof(c_core.MojoHandle) *
410 input_handles_length)
411 input_handles = <c_core.MojoHandle*>handles_alloc.memory
412 for i in xrange(input_handles_length):
413 input_handles[i] = (<Handle?>handles[i])._mojo_handle
414 cdef c_core.MojoResult res = c_core.MojoWriteMessage(self._mojo_handle,
415 buffer_as_buffer.buf,
416 input_buffer_length,
417 input_handles,
418 input_handles_length,
419 flags)
420 if res == c_core.MOJO_RESULT_OK and handles:
421 # Handles have been transferred. Let's invalidate those.
422 for handle in handles:
423 handle._Invalidate()
424 return res
425
426 def ReadMessage(self,
427 buffer=None,
428 max_number_of_handles=0,
429 flags=READ_MESSAGE_FLAG_NONE):
430 """Reads a message from the message pipe.
431
432 This method can only be used on a handle obtained from |MessagePipe()|.
433
434 This method returns a triplet of value (code, data, sizes):
435 - if code is RESULT_OK, sizes will be None, and data will be a pair of
436 (buffer, handles) where buffer is a view of the input buffer with the read
437 data, and handles is a list of received handles.
438 - if code is RESULT_RESOURCE_EXHAUSTED, data will be None and sizes will be
439 a pair of (buffer_size, handles_size) where buffer_size is the size of the
440 next message data and handles_size is the number of handles in the next
441 message.
442 - if code is any other value, data and sizes will be None.
443
444 See mojo/public/c/include/mojo/system/message_pipe.h
445 """
446 cdef _ScopedBuffer buffer_as_buffer = _ScopedBuffer(buffer, PyBUF_CONTIG)
447 cdef uint32_t input_buffer_length = buffer_as_buffer.len
448 cdef c_core.MojoHandle* input_handles = NULL
449 cdef uint32_t input_handles_length = 0
450 cdef _ScopedMemory handles_alloc = None
451 if max_number_of_handles > 0:
452 input_handles_length = max_number_of_handles
453 handles_alloc = _ScopedMemory(sizeof(c_core.MojoHandle) *
454 input_handles_length)
455 input_handles = <c_core.MojoHandle*>handles_alloc.memory
456 cdef res = c_core.MojoReadMessage(self._mojo_handle,
457 buffer_as_buffer.buf,
458 &input_buffer_length,
459 input_handles,
460 &input_handles_length,
461 flags)
462 if res == c_core.MOJO_RESULT_RESOURCE_EXHAUSTED:
463 return (res, None, (input_buffer_length, input_handles_length))
464 if res == c_core.MOJO_RESULT_OK:
465 returned_handles = [Handle(input_handles[i])
466 for i in xrange(input_handles_length)]
467 return (res,
468 (_SliceBuffer(buffer, input_buffer_length), returned_handles),
469 None)
470 return (res, None, None)
471
472 def WriteData(self, buffer=None, flags=WRITE_DATA_FLAG_NONE):
473 """
474 Writes the given data to the data pipe producer.
475
476 This method can only be used on a producer handle obtained from
477 |DataPipe()|.
478
479 This method returns a tuple (code, num_bytes).
480 - If code is RESULT_OK, num_bytes is the number of written bytes.
481 - Otherwise, num_bytes is None.
482
483 See mojo/public/c/include/mojo/system/data_pipe.h
484 """
485 cdef _ScopedBuffer buffer_as_buffer = _ScopedBuffer(buffer)
486 cdef uint32_t input_buffer_length = buffer_as_buffer.len
487 cdef c_core.MojoResult res = c_core.MojoWriteData(self._mojo_handle,
488 buffer_as_buffer.buf,
489 &input_buffer_length,
490 flags)
491 if res == c_core.MOJO_RESULT_OK:
492 return (res, input_buffer_length)
493 return (res, None)
494
495 def BeginWriteData(self,
496 flags=WRITE_DATA_FLAG_NONE):
497 """
498 Begins a two-phase write to the data pipe producer.
499
500 This method can only be used on a producer handle obtained from
501 |DataPipe()|.
502
503 This method returns a tuple (code, two_phase_buffer).
504 - If code is RESULT_OK, two_phase_buffer is a writable
505 DataPipeTwoPhaseBuffer
506 - Otherwise, two_phase_buffer is None.
507
508 See mojo/public/c/include/mojo/system/data_pipe.h
509 """
510 cdef void* out_buffer
511 cdef uint32_t out_size = 0
512 cdef c_core.MojoResult res = c_core.MojoBeginWriteData(self._mojo_handle,
513 &out_buffer,
514 &out_size,
515 flags)
516 if res != c_core.MOJO_RESULT_OK:
517 return (res, None)
518 cdef _NativeMemoryView view_buffer = _NativeMemoryView(self)
519 view_buffer.Wrap(out_buffer, out_size, read_only=False)
520 return (res, DataPipeTwoPhaseBuffer(self, memoryview(view_buffer), False))
521
522 def ReadData(self, buffer=None, flags=READ_DATA_FLAG_NONE):
523 """Reads data from the data pipe consumer.
524
525 This method can only be used on a consumer handle obtained from
526 |DataPipe()|.
527
528 This method returns a tuple (code, buffer)
529 - if code is RESULT_OK, buffer will be a view of the input buffer with the
530 read data.
531 - otherwise, buffer will be None.
532
533 See mojo/public/c/include/mojo/system/data_pipe.h
534 """
535 cdef _ScopedBuffer buffer_as_buffer = _ScopedBuffer(buffer)
536 cdef uint32_t input_buffer_length = buffer_as_buffer.len
537 cdef c_core.MojoResult res = c_core.MojoReadData(self._mojo_handle,
538 buffer_as_buffer.buf,
539 &input_buffer_length,
540 flags)
541 if res == c_core.MOJO_RESULT_OK:
542 return (res, _SliceBuffer(buffer, input_buffer_length))
543 return (res, None)
544
545 def QueryData(self, flags=READ_DATA_FLAG_NONE):
546 """Queries the amount of data available on the data pipe consumer.
547
548 This method can only be used on a consumer handle obtained from
549 |DataPipe()|.
550
551 This method returns a tuple (code, num_bytes)
552 - if code is RESULT_OK, num_bytes will be the number of bytes available on
553 the data pipe consumer.
554 - otherwise, num_bytes will be None.
555
556 See mojo/public/c/include/mojo/system/data_pipe.h
557 """
558 cdef uint32_t num_bytes = 0
559 cdef c_core.MojoResult res = c_core.MojoReadData(
560 self._mojo_handle,
561 NULL,
562 &num_bytes,
563 flags|c_core.MOJO_READ_DATA_FLAG_QUERY)
564 return (res, num_bytes)
565
566 def BeginReadData(self, flags=READ_DATA_FLAG_NONE):
567 """
568 Begins a two-phase read to the data pipe consumer.
569
570 This method can only be used on a consumer handle obtained from
571 |DataPipe()|.
572
573 This method returns a tuple (code, two_phase_buffer).
574 - If code is RESULT_OK, two_phase_buffer is a readable
575 DataPipeTwoPhaseBuffer
576 - Otherwise, two_phase_buffer is None.
577
578 See mojo/public/c/include/mojo/system/data_pipe.h
579 """
580 cdef const void* out_buffer
581 cdef uint32_t out_size = 0
582 cdef c_core.MojoResult res = c_core.MojoBeginReadData(self._mojo_handle,
583 &out_buffer,
584 &out_size,
585 flags)
586 if res != c_core.MOJO_RESULT_OK:
587 return (res, None)
588 cdef _NativeMemoryView view_buffer = _NativeMemoryView(self)
589 view_buffer.Wrap(out_buffer, out_size, read_only=True)
590 return (res, DataPipeTwoPhaseBuffer(self, memoryview(view_buffer), True))
591
592 def Duplicate(self, options=None):
593 """Duplicate the shared buffer handle.
594
595 This method can only be used on a handle obtained from
596 |CreateSharedBuffer()| or |Duplicate()|.
597
598 See mojo/public/c/include/mojo/system/buffer.h
599 """
600 cdef c_core.MojoDuplicateBufferHandleOptions coptions
601 cdef c_core.MojoDuplicateBufferHandleOptions* coptions_ptr = NULL
602 cdef c_core.MojoHandle cnew_handle = c_core.MOJO_HANDLE_INVALID
603 if options:
604 coptions.struct_size = sizeof(c_core.MojoDuplicateBufferHandleOptions)
605 coptions.flags = options.flags
606 coptions_ptr = &coptions
607 cdef c_core.MojoResult result = c_core.MojoDuplicateBufferHandle(
608 self._mojo_handle, coptions_ptr, &cnew_handle)
609 new_handle = Handle(cnew_handle)
610 if result != c_core.MOJO_RESULT_OK:
611 raise MojoException(result)
612 return new_handle
613
614 def Map(self, offset, num_bytes, flags=MAP_BUFFER_FLAG_NONE):
615 """Maps the part (at offset |offset| of length |num_bytes|) of the buffer.
616
617 This method can only be used on a handle obtained from
618 |CreateSharedBuffer()| or |Duplicate()|.
619
620 This method returns a tuple (code, mapped_buffer).
621 - If code is RESULT_OK, mapped_buffer is a readable/writable
622 MappedBuffer
623 - Otherwise, mapped_buffer is None.
624
625 See mojo/public/c/include/mojo/system/buffer.h
626 """
627 cdef void* buffer
628 res = c_core.MojoMapBuffer(self._mojo_handle,
629 offset,
630 num_bytes,
631 &buffer,
632 flags)
633 if res != c_core.MOJO_RESULT_OK:
634 return (res, None)
635 cdef _NativeMemoryView view_buffer = _NativeMemoryView(self)
636 view_buffer.Wrap(buffer, num_bytes, read_only=False)
637 return (res, MappedBuffer(self,
638 memoryview(view_buffer),
639 lambda: c_core.MojoUnmapBuffer(buffer)))
640
641 class CreateMessagePipeOptions(object):
642 """Options for creating a message pipe.
643
644 See mojo/public/c/include/mojo/system/message_pipe.h
645 """
646 FLAG_NONE = c_core.MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE
647
648 def __init__(self):
649 self.flags = CreateMessagePipeOptions.FLAG_NONE
650
651 class MessagePipe(object):
652 """Creates a message pipe.
653
654 The two ends of the message pipe are accessible with the members handle0 and
655 handle1.
656
657 See mojo/public/c/include/mojo/system/message_pipe.h
658 """
659 def __init__(self, options=None):
660 cdef c_core.MojoCreateMessagePipeOptions coptions
661 cdef c_core.MojoCreateMessagePipeOptions* coptions_ptr = NULL
662 cdef c_core.MojoHandle chandle0 = c_core.MOJO_HANDLE_INVALID
663 cdef c_core.MojoHandle chandle1 = c_core.MOJO_HANDLE_INVALID
664 if options:
665 coptions.struct_size = sizeof(c_core.MojoCreateMessagePipeOptions)
666 coptions.flags = options.flags
667 coptions_ptr = &coptions
668 cdef c_core.MojoResult result = c_core.MojoCreateMessagePipe(coptions_ptr,
669 &chandle0,
670 &chandle1)
671 self.handle0 = Handle(chandle0)
672 self.handle1 = Handle(chandle1)
673 if result != c_core.MOJO_RESULT_OK:
674 raise c_core.MojoException(result)
675
676
677 class CreateDataPipeOptions(object):
678 """Options for creating a data pipe.
679
680 See mojo/public/c/include/mojo/system/data_pipe.h
681 """
682 FLAG_NONE = c_core.MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE
683
684 def __init__(self):
685 self.flags = CreateDataPipeOptions.FLAG_NONE
686 self.element_num_bytes = 1
687 self.capacity_num_bytes = 0
688
689 class DataPipe(object):
690 """Creates a data pipe.
691
692 The producer end of the data pipe is accessible with the member
693 producer_handle and the consumer end of the data pipe is accessible with the
694 member cconsumer_handle.
695
696 See mojo/public/c/include/mojo/system/data_pipe.h
697 """
698 def __init__(self, options=None):
699 cdef c_core.MojoCreateDataPipeOptions coptions
700 cdef c_core.MojoCreateDataPipeOptions* coptions_ptr = NULL
701 cdef c_core.MojoHandle cproducer_handle = c_core.MOJO_HANDLE_INVALID
702 cdef c_core.MojoHandle cconsumer_handle = c_core.MOJO_HANDLE_INVALID
703 if options:
704 coptions.struct_size = sizeof(c_core.MojoCreateDataPipeOptions)
705 coptions.flags = options.flags
706 coptions.element_num_bytes = options.element_num_bytes
707 coptions.capacity_num_bytes = options.capacity_num_bytes
708 coptions_ptr = &coptions
709 cdef c_core.MojoResult result = c_core.MojoCreateDataPipe(coptions_ptr,
710 &cproducer_handle,
711 &cconsumer_handle)
712 self.producer_handle = Handle(cproducer_handle)
713 self.consumer_handle = Handle(cconsumer_handle)
714 if result != c_core.MOJO_RESULT_OK:
715 raise MojoException(result)
716
717 class CreateSharedBufferOptions(object):
718 """Options for creating a shared buffer.
719
720 See mojo/public/c/include/mojo/system/buffer.h
721 """
722 FLAG_NONE = c_core.MOJO_CREATE_SHARED_BUFFER_OPTIONS_FLAG_NONE
723
724 def __init__(self):
725 self.flags = CreateSharedBufferOptions.FLAG_NONE
726
727 def CreateSharedBuffer(num_bytes, options=None):
728 """Creates a buffer of size |num_bytes| bytes that can be shared.
729
730 See mojo/public/c/include/mojo/system/buffer.h
731 """
732 cdef c_core.MojoCreateSharedBufferOptions coptions
733 cdef c_core.MojoCreateSharedBufferOptions* coptions_ptr = NULL
734 cdef c_core.MojoHandle chandle = c_core.MOJO_HANDLE_INVALID
735 if options:
736 coptions.struct_size = sizeof(c_core.MojoCreateSharedBufferOptions)
737 coptions.flags = options.flags
738 coptions_ptr = &coptions
739 cdef c_core.MojoResult result = c_core.MojoCreateSharedBuffer(coptions_ptr,
740 num_bytes,
741 &chandle)
742 handle = Handle(chandle)
743 if result != c_core.MOJO_RESULT_OK:
744 raise MojoException(result)
745 return handle
746
747 class DuplicateSharedBufferOptions(object):
748 """Options for duplicating a shared buffer.
749
750 See mojo/public/c/include/mojo/system/buffer.h
751 """
752 FLAG_NONE = c_core.MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE
753
754 def __init__(self):
755 self.flags = DuplicateSharedBufferOptions.FLAG_NONE
756
757
758 # Keeps a thread local weak reference to the current run loop.
759 _RUN_LOOPS = threading.local()
760
761
762 class RunLoop(object):
763 """RunLoop to use when using asynchronous operations on handles."""
764
765 def __init__(self):
766 self.__run_loop = mojo_system_impl.RunLoop()
767 _RUN_LOOPS.loop = weakref.ref(self)
768
769 def __del__(self):
770 del _RUN_LOOPS.loop
771
772 def Run(self):
773 """Run the runloop until Quit is called."""
774 return self.__run_loop.Run()
775
776 def RunUntilIdle(self):
777 """Run the runloop until Quit is called or no operation is waiting."""
778 return self.__run_loop.RunUntilIdle()
779
780 def Quit(self):
781 """Quit the runloop."""
782 return self.__run_loop.Quit()
783
784 def PostDelayedTask(self, runnable, delay=0):
785 """
786 Post a task on the runloop. This must be called from the thread owning the
787 runloop.
788 """
789 return self.__run_loop.PostDelayedTask(runnable, delay)
790
791 @staticmethod
792 def Current():
793 if hasattr(_RUN_LOOPS, 'loop'):
794 return _RUN_LOOPS.loop()
795 return None
796
797
798 _ASYNC_WAITER = mojo_system_impl.AsyncWaiter()
OLDNEW
« no previous file with comments | « mojo/public/python/mojo_bindings/serialization.py ('k') | mojo/public/python/mojo_system_impl.pyx » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698