diff options
Diffstat (limited to 'mojo/public/python/mojo_system.pyx')
-rw-r--r-- | mojo/public/python/mojo_system.pyx | 804 |
1 files changed, 0 insertions, 804 deletions
diff --git a/mojo/public/python/mojo_system.pyx b/mojo/public/python/mojo_system.pyx deleted file mode 100644 index 4e684af..0000000 --- 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() |