Index: mojo/public/python/mojo_system.pyx |
diff --git a/mojo/public/python/mojo_system.pyx b/mojo/public/python/mojo_system.pyx |
deleted file mode 100644 |
index 4e684af5ccc72774d82de3c11f1a7e38094f32e4..0000000000000000000000000000000000000000 |
--- a/mojo/public/python/mojo_system.pyx |
+++ /dev/null |
@@ -1,804 +0,0 @@ |
-# Copyright 2014 The Chromium Authors. All rights reserved. |
-# Use of this source code is governed by a BSD-style license that can be |
-# found in the LICENSE file. |
- |
-# distutils language = c++ |
- |
-cimport c_core |
-cimport c_export # needed so the init function gets exported |
-cimport c_thunks |
- |
- |
-from cpython.buffer cimport PyBUF_CONTIG |
-from cpython.buffer cimport PyBUF_CONTIG_RO |
-from cpython.buffer cimport Py_buffer |
-from cpython.buffer cimport PyBuffer_FillInfo |
-from cpython.buffer cimport PyBuffer_Release |
-from cpython.buffer cimport PyObject_GetBuffer |
-from cpython.mem cimport PyMem_Malloc, PyMem_Free |
-from cpython.object cimport Py_EQ, Py_NE |
-from libc.stdint cimport int32_t, int64_t, uint32_t, uint64_t, uintptr_t |
- |
-import ctypes |
-import threading |
- |
-import mojo_system_impl |
- |
-def SetSystemThunks(system_thunks_as_object): |
- """Bind the basic Mojo Core functions. |
- |
- This should only be used by the embedder. |
- """ |
- cdef const c_thunks.MojoSystemThunks* system_thunks = ( |
- <const c_thunks.MojoSystemThunks*><uintptr_t>system_thunks_as_object) |
- c_thunks.MojoSetSystemThunks(system_thunks) |
- |
-HANDLE_INVALID = c_core.MOJO_HANDLE_INVALID |
-RESULT_OK = c_core.MOJO_RESULT_OK |
-RESULT_CANCELLED = c_core.MOJO_RESULT_CANCELLED |
-RESULT_UNKNOWN = c_core.MOJO_RESULT_UNKNOWN |
-RESULT_INVALID_ARGUMENT = c_core.MOJO_RESULT_INVALID_ARGUMENT |
-RESULT_DEADLINE_EXCEEDED = c_core.MOJO_RESULT_DEADLINE_EXCEEDED |
-RESULT_NOT_FOUND = c_core.MOJO_RESULT_NOT_FOUND |
-RESULT_ALREADY_EXISTS = c_core.MOJO_RESULT_ALREADY_EXISTS |
-RESULT_PERMISSION_DENIED = c_core.MOJO_RESULT_PERMISSION_DENIED |
-RESULT_RESOURCE_EXHAUSTED = c_core.MOJO_RESULT_RESOURCE_EXHAUSTED |
-RESULT_FAILED_PRECONDITION = c_core.MOJO_RESULT_FAILED_PRECONDITION |
-RESULT_ABORTED = c_core.MOJO_RESULT_ABORTED |
-RESULT_OUT_OF_RANGE = c_core.MOJO_RESULT_OUT_OF_RANGE |
-RESULT_UNIMPLEMENTED = c_core.MOJO_RESULT_UNIMPLEMENTED |
-RESULT_INTERNAL = c_core.MOJO_RESULT_INTERNAL |
-RESULT_UNAVAILABLE = c_core.MOJO_RESULT_UNAVAILABLE |
-RESULT_DATA_LOSS = c_core.MOJO_RESULT_DATA_LOSS |
-RESULT_BUSY = c_core.MOJO_RESULT_BUSY |
-RESULT_SHOULD_WAIT = c_core.MOJO_RESULT_SHOULD_WAIT |
-DEADLINE_INDEFINITE = c_core.MOJO_DEADLINE_INDEFINITE |
-HANDLE_SIGNAL_NONE = c_core.MOJO_HANDLE_SIGNAL_NONE |
-HANDLE_SIGNAL_READABLE = c_core.MOJO_HANDLE_SIGNAL_READABLE |
-HANDLE_SIGNAL_WRITABLE = c_core.MOJO_HANDLE_SIGNAL_WRITABLE |
-HANDLE_SIGNAL_PEER_CLOSED = c_core.MOJO_HANDLE_SIGNAL_PEER_CLOSED |
-WRITE_MESSAGE_FLAG_NONE = c_core.MOJO_WRITE_MESSAGE_FLAG_NONE |
-READ_MESSAGE_FLAG_NONE = c_core.MOJO_READ_MESSAGE_FLAG_NONE |
-READ_MESSAGE_FLAG_MAY_DISCARD = c_core.MOJO_READ_MESSAGE_FLAG_MAY_DISCARD |
-WRITE_DATA_FLAG_NONE = c_core.MOJO_WRITE_DATA_FLAG_NONE |
-WRITE_DATA_FLAG_ALL_OR_NONE = c_core.MOJO_WRITE_DATA_FLAG_ALL_OR_NONE |
-READ_DATA_FLAG_NONE = c_core.MOJO_READ_DATA_FLAG_NONE |
-READ_DATA_FLAG_ALL_OR_NONE = c_core.MOJO_READ_DATA_FLAG_ALL_OR_NONE |
-READ_DATA_FLAG_DISCARD = c_core.MOJO_READ_DATA_FLAG_DISCARD |
-READ_DATA_FLAG_QUERY = c_core.MOJO_READ_DATA_FLAG_QUERY |
-READ_DATA_FLAG_PEEK = c_core.MOJO_READ_DATA_FLAG_PEEK |
-MAP_BUFFER_FLAG_NONE = c_core.MOJO_MAP_BUFFER_FLAG_NONE |
- |
-_WAITMANY_NO_SIGNAL_STATE_ERRORS = [RESULT_INVALID_ARGUMENT, |
- RESULT_RESOURCE_EXHAUSTED] |
- |
-def GetTimeTicksNow(): |
- """Monotonically increasing tick count representing "right now." |
- |
- See mojo/public/c/system/functions.h |
- """ |
- return c_core.MojoGetTimeTicksNow() |
- |
-cdef class _ScopedMemory: |
- """Allocate memory at creation, and deallocate it at destruction.""" |
- cdef void* memory |
- def __init__(self, size): |
- self.memory = PyMem_Malloc(size) |
- |
- def __dealloc__(self): |
- PyMem_Free(self.memory) |
- |
-cdef class _ScopedBuffer: |
- """Retrieve pointer to a buffer a creation, and release it at destruction. |
- """ |
- cdef Py_buffer _buf |
- cdef void* buf |
- cdef Py_ssize_t len |
- |
- def __init__(self, obj, flags=PyBUF_CONTIG_RO): |
- if obj: |
- if PyObject_GetBuffer(obj, &self._buf, flags) < 0: |
- raise TypeError('Unable to read buffer.') |
- self.buf = self._buf.buf |
- self.len = self._buf.len |
- else: |
- self.buf = NULL |
- self.len = 0 |
- |
- def __dealloc__(self): |
- if self.buf: |
- PyBuffer_Release(&self._buf) |
- |
-def _SliceBuffer(buffer, size): |
- """Slice the given buffer, reducing it to the given size. |
- |
- Return None if None is passed in. |
- """ |
- if not buffer: |
- return buffer |
- return buffer[:size] |
- |
-cdef class _NativeMemoryView(object): |
- """Create a python buffer wrapping the given memory. |
- |
- Will also retain the given handle until this object is deallocated. |
- """ |
- cdef void* _memory |
- cdef uint32_t _size |
- cdef char _read_only |
- cdef char _wrapped |
- cdef object _handle |
- |
- def __init__(self, handle): |
- self._handle = handle |
- |
- def __cinit__(self): |
- self._memory = NULL |
- self._size = 0 |
- self._read_only = True |
- self._wrapped = False |
- |
- cdef Wrap(self, |
- const void* memory, |
- uint32_t size, |
- read_only=True): |
- """Makes this buffer wraps the given memory. |
- |
- Must be called before using this buffer, and must only be called once. |
- """ |
- assert not self._wrapped |
- self._wrapped = True |
- self._memory = <void*>memory |
- self._size = size |
- self._read_only = read_only |
- |
- # buffer interface (PEP 3118) |
- def __getbuffer__(self, Py_buffer *view, int flags): |
- assert self._wrapped |
- if view == NULL: |
- return |
- PyBuffer_FillInfo(view, |
- self, |
- self._memory, |
- self._size, |
- self._read_only, |
- flags) |
- |
- def __releasebuffer__(self, Py_buffer *view): |
- assert self._wrapped |
- pass |
- |
- # legacy buffer interface |
- def __getsegcount__(self, Py_ssize_t *sizes): |
- assert self._wrapped |
- if sizes != NULL: |
- sizes[0] = self._size |
- return 1 |
- |
- def __getreadbuffer__(self, Py_ssize_t index, void **data): |
- assert self._wrapped |
- if index != 0: |
- raise SystemError('Index out of bounds: %d' % index) |
- data[0] = self._memory |
- return self._size |
- |
- def __getwritebuffer__(self, Py_ssize_t index, void **data): |
- assert self._wrapped |
- if index != 0: |
- raise SystemError('Index out of bounds: %d' % index) |
- if self._read_only: |
- raise TypeError('Buffer is read-only.') |
- data[0] = self._memory |
- return self._size |
- |
-class MojoException(Exception): |
- """Exception wrapping a mojo result error code.""" |
- |
- def __init__(self, mojo_result): |
- self.mojo_result = mojo_result |
- |
-def WaitMany(handles_and_signals, deadline): |
- """Waits on a list of handles. |
- |
- Args: |
- handles_and_signals: list of tuples of handle and signal. |
- |
- See mojo/public/c/system/functions.h |
- """ |
- cdef uint32_t length = len(handles_and_signals) |
- cdef uint32_t result_index = <uint32_t>(-1) |
- |
- cdef _ScopedMemory handles_alloc = _ScopedMemory( |
- sizeof(c_core.MojoHandle) * length) |
- cdef _ScopedMemory signals_alloc = _ScopedMemory( |
- sizeof(c_core.MojoHandleSignals) * length) |
- cdef _ScopedMemory states_alloc = _ScopedMemory( |
- sizeof(c_core.MojoHandleSignalsState) * length) |
- cdef c_core.MojoHandle* handles = <c_core.MojoHandle*>handles_alloc.memory |
- cdef c_core.MojoHandleSignals* signals = ( |
- <c_core.MojoHandleSignals*>signals_alloc.memory) |
- cdef c_core.MojoHandleSignalsState* states = ( |
- <c_core.MojoHandleSignalsState*>states_alloc.memory) |
- cdef int index = 0 |
- for (h, s) in handles_and_signals: |
- handles[index] = (<Handle?>h)._mojo_handle |
- signals[index] = s |
- index += 1 |
- cdef c_core.MojoResult result = c_core.MOJO_RESULT_OK |
- cdef c_core.MojoDeadline cdeadline = deadline |
- with nogil: |
- result = c_core.MojoWaitMany(handles, signals, length, cdeadline, |
- &result_index, states) |
- |
- returned_result_index = None |
- if result_index != <uint32_t>(-1): |
- returned_result_index = result_index |
- |
- returned_states = None |
- if result not in _WAITMANY_NO_SIGNAL_STATE_ERRORS: |
- returned_states = [(states[i].satisfied_signals, |
- states[i].satisfiable_signals) for i in xrange(length)] |
- |
- return (result, returned_result_index, returned_states) |
- |
- |
-cdef class DataPipeTwoPhaseBuffer(object): |
- """Return value for two phases read and write. |
- |
- The buffer field contains the python buffer where data can be read or written. |
- When done with the buffer, the |end| method must be called with the number of |
- bytes read or written. |
- """ |
- |
- cdef object _buffer |
- cdef Handle _handle |
- cdef char _read |
- |
- def __init__(self, handle, buffer, read=True): |
- self._buffer = buffer |
- self._handle = handle |
- self._read = read |
- |
- def End(self, num_bytes): |
- self._buffer = None |
- cdef c_core.MojoResult result |
- if self._read: |
- result = c_core.MojoEndReadData(self._handle._mojo_handle, num_bytes) |
- else: |
- result = c_core.MojoEndWriteData(self._handle._mojo_handle, num_bytes) |
- self._handle = None |
- return result |
- |
- @property |
- def buffer(self): |
- return self._buffer |
- |
- def __dealloc__(self): |
- assert not self._buffer |
- |
-cdef class MappedBuffer(object): |
- """Return value for the |map| operation on shared buffer handles. |
- |
- The buffer field contains the python buffer where data can be read or written. |
- When done with the buffer, the |unmap| method must be called. |
- """ |
- |
- cdef object _buffer |
- cdef object _handle |
- cdef object _cleanup |
- |
- def __init__(self, handle, buffer, cleanup): |
- self._buffer = buffer |
- self._handle = handle |
- self._cleanup = cleanup |
- |
- def UnMap(self): |
- self._buffer = None |
- cdef c_core.MojoResult result = self._cleanup() |
- self._cleanup = None |
- self._handle = None |
- return result |
- |
- @property |
- def buffer(self): |
- return self._buffer |
- |
- def __dealloc__(self): |
- if self._buffer: |
- self.UnMap() |
- |
-cdef class Handle(object): |
- """A mojo object.""" |
- |
- cdef c_core.MojoHandle _mojo_handle |
- |
- def __init__(self, mojo_handle=c_core.MOJO_HANDLE_INVALID): |
- self._mojo_handle = mojo_handle |
- |
- def _Invalidate(self): |
- """Invalidate the current handle. |
- |
- The close operation is not called. It is the responsability of the caller to |
- ensure that the handle is not leaked. |
- """ |
- self._mojo_handle = c_core.MOJO_HANDLE_INVALID |
- |
- def __richcmp__(self, other, op): |
- if op != Py_EQ and op != Py_NE: |
- raise TypeError('Handle is not ordered') |
- cdef int equality |
- if type(self) is not type(other): |
- equality = id(self) == id(other) |
- else: |
- equality = (<Handle>self)._mojo_handle == (<Handle>other)._mojo_handle |
- if op == Py_EQ: |
- return equality |
- else: |
- return not equality |
- |
- def IsValid(self): |
- """Returns whether this handle is valid.""" |
- return self._mojo_handle != c_core.MOJO_HANDLE_INVALID |
- |
- def Close(self): |
- """Closes this handle. |
- |
- See mojo/public/c/system/functions.h |
- """ |
- cdef c_core.MojoResult result = c_core.MOJO_RESULT_OK |
- if self.IsValid(): |
- result = c_core.MojoClose(self._mojo_handle) |
- self._Invalidate() |
- return result |
- |
- def __dealloc__(self): |
- self.Close() |
- |
- def Wait(self, signals, deadline): |
- """Waits on the given handle. |
- |
- See mojo/public/c/system/functions.h |
- """ |
- cdef c_core.MojoHandle handle = self._mojo_handle |
- cdef c_core.MojoHandleSignals csignals = signals |
- cdef c_core.MojoDeadline cdeadline = deadline |
- cdef c_core.MojoHandleSignalsState signal_states |
- cdef c_core.MojoResult result |
- with nogil: |
- result = c_core.MojoWait(handle, csignals, cdeadline, &signal_states) |
- |
- returned_states = None |
- if result not in _WAITMANY_NO_SIGNAL_STATE_ERRORS: |
- returned_states = (signal_states.satisfied_signals, |
- signal_states.satisfiable_signals) |
- |
- return (result, returned_states) |
- |
- def AsyncWait(self, signals, deadline, callback): |
- cdef c_core.MojoHandle handle = self._mojo_handle |
- cdef c_core.MojoHandleSignals csignals = signals |
- cdef c_core.MojoDeadline cdeadline = deadline |
- wait_id = _ASYNC_WAITER.AsyncWait( |
- handle, |
- csignals, |
- cdeadline, |
- callback) |
- def cancel(): |
- _ASYNC_WAITER.CancelWait(wait_id) |
- return cancel |
- |
- def WriteMessage(self, |
- buffer=None, |
- handles=None, |
- flags=WRITE_MESSAGE_FLAG_NONE): |
- """Writes a message to the message pipe. |
- |
- This method can only be used on a handle obtained from |MessagePipe()|. |
- |
- See mojo/public/c/system/message_pipe.h |
- """ |
- cdef _ScopedBuffer buffer_as_buffer = _ScopedBuffer(buffer) |
- cdef uint32_t input_buffer_length = buffer_as_buffer.len |
- cdef c_core.MojoHandle* input_handles = NULL |
- cdef uint32_t input_handles_length = 0 |
- cdef _ScopedMemory handles_alloc = None |
- if handles: |
- input_handles_length = len(handles) |
- handles_alloc = _ScopedMemory(sizeof(c_core.MojoHandle) * |
- input_handles_length) |
- input_handles = <c_core.MojoHandle*>handles_alloc.memory |
- for i in xrange(input_handles_length): |
- input_handles[i] = (<Handle?>handles[i])._mojo_handle |
- cdef c_core.MojoResult res = c_core.MojoWriteMessage(self._mojo_handle, |
- buffer_as_buffer.buf, |
- input_buffer_length, |
- input_handles, |
- input_handles_length, |
- flags) |
- if res == c_core.MOJO_RESULT_OK and handles: |
- # Handles have been transferred. Let's invalidate those. |
- for handle in handles: |
- handle._Invalidate() |
- return res |
- |
- def ReadMessage(self, |
- buffer=None, |
- max_number_of_handles=0, |
- flags=READ_MESSAGE_FLAG_NONE): |
- """Reads a message from the message pipe. |
- |
- This method can only be used on a handle obtained from |MessagePipe()|. |
- |
- This method returns a triplet of value (code, data, sizes): |
- - if code is RESULT_OK, sizes will be None, and data will be a pair of |
- (buffer, handles) where buffer is a view of the input buffer with the read |
- data, and handles is a list of received handles. |
- - if code is RESULT_RESOURCE_EXHAUSTED, data will be None and sizes will be |
- a pair of (buffer_size, handles_size) where buffer_size is the size of the |
- next message data and handles_size is the number of handles in the next |
- message. |
- - if code is any other value, data and sizes will be None. |
- |
- See mojo/public/c/system/message_pipe.h |
- """ |
- cdef _ScopedBuffer buffer_as_buffer = _ScopedBuffer(buffer, PyBUF_CONTIG) |
- cdef uint32_t input_buffer_length = buffer_as_buffer.len |
- cdef c_core.MojoHandle* input_handles = NULL |
- cdef uint32_t input_handles_length = 0 |
- cdef _ScopedMemory handles_alloc = None |
- if max_number_of_handles > 0: |
- input_handles_length = max_number_of_handles |
- handles_alloc = _ScopedMemory(sizeof(c_core.MojoHandle) * |
- input_handles_length) |
- input_handles = <c_core.MojoHandle*>handles_alloc.memory |
- cdef res = c_core.MojoReadMessage(self._mojo_handle, |
- buffer_as_buffer.buf, |
- &input_buffer_length, |
- input_handles, |
- &input_handles_length, |
- flags) |
- if res == c_core.MOJO_RESULT_RESOURCE_EXHAUSTED: |
- return (res, None, (input_buffer_length, input_handles_length)) |
- if res == c_core.MOJO_RESULT_OK: |
- returned_handles = [Handle(input_handles[i]) |
- for i in xrange(input_handles_length)] |
- return (res, |
- (_SliceBuffer(buffer, input_buffer_length), returned_handles), |
- None) |
- return (res, None, None) |
- |
- def WriteData(self, buffer=None, flags=WRITE_DATA_FLAG_NONE): |
- """ |
- Writes the given data to the data pipe producer. |
- |
- This method can only be used on a producer handle obtained from |
- |DataPipe()|. |
- |
- This method returns a tuple (code, num_bytes). |
- - If code is RESULT_OK, num_bytes is the number of written bytes. |
- - Otherwise, num_bytes is None. |
- |
- See mojo/public/c/system/data_pipe.h |
- """ |
- cdef _ScopedBuffer buffer_as_buffer = _ScopedBuffer(buffer) |
- cdef uint32_t input_buffer_length = buffer_as_buffer.len |
- cdef c_core.MojoResult res = c_core.MojoWriteData(self._mojo_handle, |
- buffer_as_buffer.buf, |
- &input_buffer_length, |
- flags) |
- if res == c_core.MOJO_RESULT_OK: |
- return (res, input_buffer_length) |
- return (res, None) |
- |
- def BeginWriteData(self, |
- min_size=None, |
- flags=WRITE_DATA_FLAG_NONE): |
- """ |
- Begins a two-phase write to the data pipe producer. |
- |
- This method can only be used on a producer handle obtained from |
- |DataPipe()|. |
- |
- This method returns a tuple (code, two_phase_buffer). |
- - If code is RESULT_OK, two_phase_buffer is a writable |
- DataPipeTwoPhaseBuffer |
- - Otherwise, two_phase_buffer is None. |
- |
- See mojo/public/c/system/data_pipe.h |
- """ |
- cdef void* out_buffer |
- cdef uint32_t out_size = 0 |
- if min_size: |
- flags |= c_core.MOJO_WRITE_DATA_FLAG_ALL_OR_NONE |
- out_size = min_size |
- cdef c_core.MojoResult res = c_core.MojoBeginWriteData(self._mojo_handle, |
- &out_buffer, |
- &out_size, |
- flags) |
- if res != c_core.MOJO_RESULT_OK: |
- return (res, None) |
- cdef _NativeMemoryView view_buffer = _NativeMemoryView(self) |
- view_buffer.Wrap(out_buffer, out_size, read_only=False) |
- return (res, DataPipeTwoPhaseBuffer(self, memoryview(view_buffer), False)) |
- |
- def ReadData(self, buffer=None, flags=READ_DATA_FLAG_NONE): |
- """Reads data from the data pipe consumer. |
- |
- This method can only be used on a consumer handle obtained from |
- |DataPipe()|. |
- |
- This method returns a tuple (code, buffer) |
- - if code is RESULT_OK, buffer will be a view of the input buffer with the |
- read data. |
- - otherwise, buffer will be None. |
- |
- See mojo/public/c/system/data_pipe.h |
- """ |
- cdef _ScopedBuffer buffer_as_buffer = _ScopedBuffer(buffer) |
- cdef uint32_t input_buffer_length = buffer_as_buffer.len |
- cdef c_core.MojoResult res = c_core.MojoReadData(self._mojo_handle, |
- buffer_as_buffer.buf, |
- &input_buffer_length, |
- flags) |
- if res == c_core.MOJO_RESULT_OK: |
- return (res, _SliceBuffer(buffer, input_buffer_length)) |
- return (res, None) |
- |
- def QueryData(self, flags=READ_DATA_FLAG_NONE): |
- """Queries the amount of data available on the data pipe consumer. |
- |
- This method can only be used on a consumer handle obtained from |
- |DataPipe()|. |
- |
- This method returns a tuple (code, num_bytes) |
- - if code is RESULT_OK, num_bytes will be the number of bytes available on |
- the data pipe consumer. |
- - otherwise, num_bytes will be None. |
- |
- See mojo/public/c/system/data_pipe.h |
- """ |
- cdef uint32_t num_bytes = 0 |
- cdef c_core.MojoResult res = c_core.MojoReadData( |
- self._mojo_handle, |
- NULL, |
- &num_bytes, |
- flags|c_core.MOJO_READ_DATA_FLAG_QUERY) |
- return (res, num_bytes) |
- |
- def BeginReadData(self, min_size=None, flags=READ_DATA_FLAG_NONE): |
- """ |
- Begins a two-phase read to the data pipe consumer. |
- |
- This method can only be used on a consumer handle obtained from |
- |DataPipe()|. |
- |
- This method returns a tuple (code, two_phase_buffer). |
- - If code is RESULT_OK, two_phase_buffer is a readable |
- DataPipeTwoPhaseBuffer |
- - Otherwise, two_phase_buffer is None. |
- |
- See mojo/public/c/system/data_pipe.h |
- """ |
- cdef const void* out_buffer |
- cdef uint32_t out_size = 0 |
- if min_size: |
- flags |= c_core.MOJO_READ_DATA_FLAG_ALL_OR_NONE |
- out_size = min_size |
- cdef c_core.MojoResult res = c_core.MojoBeginReadData(self._mojo_handle, |
- &out_buffer, |
- &out_size, |
- flags) |
- if res != c_core.MOJO_RESULT_OK: |
- return (res, None) |
- cdef _NativeMemoryView view_buffer = _NativeMemoryView(self) |
- view_buffer.Wrap(out_buffer, out_size, read_only=True) |
- return (res, DataPipeTwoPhaseBuffer(self, memoryview(view_buffer), True)) |
- |
- def Duplicate(self, options=None): |
- """Duplicate the shared buffer handle. |
- |
- This method can only be used on a handle obtained from |
- |CreateSharedBuffer()| or |Duplicate()|. |
- |
- See mojo/public/c/system/buffer.h |
- """ |
- cdef c_core.MojoDuplicateBufferHandleOptions coptions |
- cdef c_core.MojoDuplicateBufferHandleOptions* coptions_ptr = NULL |
- cdef c_core.MojoHandle cnew_handle = c_core.MOJO_HANDLE_INVALID |
- if options: |
- coptions.struct_size = sizeof(c_core.MojoDuplicateBufferHandleOptions) |
- coptions.flags = options.flags |
- coptions_ptr = &coptions |
- cdef c_core.MojoResult result = c_core.MojoDuplicateBufferHandle( |
- self._mojo_handle, coptions_ptr, &cnew_handle) |
- new_handle = Handle(cnew_handle) |
- if result != c_core.MOJO_RESULT_OK: |
- raise MojoException(result) |
- return new_handle |
- |
- def Map(self, offset, num_bytes, flags=MAP_BUFFER_FLAG_NONE): |
- """Maps the part (at offset |offset| of length |num_bytes|) of the buffer. |
- |
- This method can only be used on a handle obtained from |
- |CreateSharedBuffer()| or |Duplicate()|. |
- |
- This method returns a tuple (code, mapped_buffer). |
- - If code is RESULT_OK, mapped_buffer is a readable/writable |
- MappedBuffer |
- - Otherwise, mapped_buffer is None. |
- |
- See mojo/public/c/system/buffer.h |
- """ |
- cdef void* buffer |
- res = c_core.MojoMapBuffer(self._mojo_handle, |
- offset, |
- num_bytes, |
- &buffer, |
- flags) |
- if res != c_core.MOJO_RESULT_OK: |
- return (res, None) |
- cdef _NativeMemoryView view_buffer = _NativeMemoryView(self) |
- view_buffer.Wrap(buffer, num_bytes, read_only=False) |
- return (res, MappedBuffer(self, |
- memoryview(view_buffer), |
- lambda: c_core.MojoUnmapBuffer(buffer))) |
- |
-class CreateMessagePipeOptions(object): |
- """Options for creating a message pipe. |
- |
- See mojo/public/c/system/message_pipe.h |
- """ |
- FLAG_NONE = c_core.MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE |
- |
- def __init__(self): |
- self.flags = CreateMessagePipeOptions.FLAG_NONE |
- |
-class MessagePipe(object): |
- """Creates a message pipe. |
- |
- The two ends of the message pipe are accessible with the members handle0 and |
- handle1. |
- |
- See mojo/public/c/system/message_pipe.h |
- """ |
- def __init__(self, options=None): |
- cdef c_core.MojoCreateMessagePipeOptions coptions |
- cdef c_core.MojoCreateMessagePipeOptions* coptions_ptr = NULL |
- cdef c_core.MojoHandle chandle0 = c_core.MOJO_HANDLE_INVALID |
- cdef c_core.MojoHandle chandle1 = c_core.MOJO_HANDLE_INVALID |
- if options: |
- coptions.struct_size = sizeof(c_core.MojoCreateMessagePipeOptions) |
- coptions.flags = options.flags |
- coptions_ptr = &coptions |
- cdef c_core.MojoResult result = c_core.MojoCreateMessagePipe(coptions_ptr, |
- &chandle0, |
- &chandle1) |
- self.handle0 = Handle(chandle0) |
- self.handle1 = Handle(chandle1) |
- if result != c_core.MOJO_RESULT_OK: |
- raise c_core.MojoException(result) |
- |
- |
-class CreateDataPipeOptions(object): |
- """Options for creating a data pipe. |
- |
- See mojo/public/c/system/data_pipe.h |
- """ |
- FLAG_NONE = c_core.MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE |
- FLAG_MAY_DISCARD = c_core.MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD |
- |
- def __init__(self): |
- self.flags = CreateDataPipeOptions.FLAG_NONE |
- self.element_num_bytes = 1 |
- self.capacity_num_bytes = 0 |
- |
-class DataPipe(object): |
- """Creates a data pipe. |
- |
- The producer end of the data pipe is accessible with the member |
- producer_handle and the consumer end of the data pipe is accessible with the |
- member cconsumer_handle. |
- |
- See mojo/public/c/system/data_pipe.h |
- """ |
- def __init__(self, options=None): |
- cdef c_core.MojoCreateDataPipeOptions coptions |
- cdef c_core.MojoCreateDataPipeOptions* coptions_ptr = NULL |
- cdef c_core.MojoHandle cproducer_handle = c_core.MOJO_HANDLE_INVALID |
- cdef c_core.MojoHandle cconsumer_handle = c_core.MOJO_HANDLE_INVALID |
- if options: |
- coptions.struct_size = sizeof(c_core.MojoCreateDataPipeOptions) |
- coptions.flags = options.flags |
- coptions.element_num_bytes = options.element_num_bytes |
- coptions.capacity_num_bytes = options.capacity_num_bytes |
- coptions_ptr = &coptions |
- cdef c_core.MojoResult result = c_core.MojoCreateDataPipe(coptions_ptr, |
- &cproducer_handle, |
- &cconsumer_handle) |
- self.producer_handle = Handle(cproducer_handle) |
- self.consumer_handle = Handle(cconsumer_handle) |
- if result != c_core.MOJO_RESULT_OK: |
- raise MojoException(result) |
- |
-class CreateSharedBufferOptions(object): |
- """Options for creating a shared buffer. |
- |
- See mojo/public/c/system/buffer.h |
- """ |
- FLAG_NONE = c_core.MOJO_CREATE_SHARED_BUFFER_OPTIONS_FLAG_NONE |
- |
- def __init__(self): |
- self.flags = CreateSharedBufferOptions.FLAG_NONE |
- |
-def CreateSharedBuffer(num_bytes, options=None): |
- """Creates a buffer of size |num_bytes| bytes that can be shared. |
- |
- See mojo/public/c/system/buffer.h |
- """ |
- cdef c_core.MojoCreateSharedBufferOptions coptions |
- cdef c_core.MojoCreateSharedBufferOptions* coptions_ptr = NULL |
- cdef c_core.MojoHandle chandle = c_core.MOJO_HANDLE_INVALID |
- if options: |
- coptions.struct_size = sizeof(c_core.MojoCreateSharedBufferOptions) |
- coptions.flags = options.flags |
- coptions_ptr = &coptions |
- cdef c_core.MojoResult result = c_core.MojoCreateSharedBuffer(coptions_ptr, |
- num_bytes, |
- &chandle) |
- handle = Handle(chandle) |
- if result != c_core.MOJO_RESULT_OK: |
- raise MojoException(result) |
- return handle |
- |
-class DuplicateSharedBufferOptions(object): |
- """Options for duplicating a shared buffer. |
- |
- See mojo/public/c/system/buffer.h |
- """ |
- FLAG_NONE = c_core.MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE |
- |
- def __init__(self): |
- self.flags = DuplicateSharedBufferOptions.FLAG_NONE |
- |
- |
-# Keeps a thread local weak reference to the current run loop. |
-_RUN_LOOPS = threading.local() |
- |
- |
-class RunLoop(object): |
- """RunLoop to use when using asynchronous operations on handles.""" |
- |
- def __init__(self): |
- self.__run_loop = mojo_system_impl.RunLoop() |
- _RUN_LOOPS.loop = id(self) |
- |
- def __del__(self): |
- del _RUN_LOOPS.loop |
- |
- def Run(self): |
- """Run the runloop until Quit is called.""" |
- return self.__run_loop.Run() |
- |
- def RunUntilIdle(self): |
- """Run the runloop until Quit is called or no operation is waiting.""" |
- return self.__run_loop.RunUntilIdle() |
- |
- def Quit(self): |
- """Quit the runloop.""" |
- return self.__run_loop.Quit() |
- |
- def PostDelayedTask(self, runnable, delay=0): |
- """ |
- Post a task on the runloop. This must be called from the thread owning the |
- runloop. |
- """ |
- return self.__run_loop.PostDelayedTask(runnable, delay) |
- |
- @staticmethod |
- def Current(): |
- if hasattr(_RUN_LOOPS, 'loop'): |
- return ctypes.cast(_RUN_LOOPS.loop, ctypes.py_object).value |
- return None |
- |
- |
-_ASYNC_WAITER = mojo_system_impl.AsyncWaiter() |