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

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

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