Skip to content

Commit

Permalink
Merge 0abca54 into 4d54894
Browse files Browse the repository at this point in the history
  • Loading branch information
tonyseek committed May 9, 2018
2 parents 4d54894 + 0abca54 commit 95f26a2
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 5 deletions.
12 changes: 12 additions & 0 deletions README.rst
@@ -1,3 +1,5 @@
|Build Status| |Coverage Status| |PyPI Version| |Wheel Status|

orphanage
=========

Expand Down Expand Up @@ -74,3 +76,13 @@ Of course, pull requests are always welcome.
.. _Gunicorn: https://github.com/benoitc/gunicorn
.. _CaoE: https://github.com/douban/CaoE
.. _GitHub: https://github.com/tonyseek/python-orphanage/issues

.. |Build Status| image:: https://travis-ci.org/tonyseek/python-orphanage.svg?branch=master
:target: https://travis-ci.org/tonyseek/python-orphanage
:alt: Build Status
.. |Coverage Status| image:: https://coveralls.io/repos/github/tonyseek/python-orphanage/badge.svg?branch=master
:target: https://coveralls.io/github/tonyseek/python-orphanage?branch=master
:alt: Coverage Status
.. |PyPI Version| image:: https://img.shields.io/pypi/v/python-orphanage.svg
:target: https://pypi.org/project/openvpn-status/
:alt: PyPI Version
20 changes: 20 additions & 0 deletions docs/api.rst
@@ -0,0 +1,20 @@
API Reference
-------------

For most users, please use the public API instead of the internal one.

.. _public_api:

Public API
~~~~~~~~~~

.. automodule:: orphanage
:members:


Internal API
~~~~~~~~~~~~

.. automodule:: orphanage.poll
:members:
:undoc-members:
4 changes: 2 additions & 2 deletions docs/development.rst
@@ -1,5 +1,5 @@
Development
-----------
Development Guide
-----------------

There is a ``Makefile`` for development in local environment.
See available commands via invoking ``make help``.
Expand Down
13 changes: 10 additions & 3 deletions docs/index.rst
@@ -1,12 +1,19 @@
Document of orphanage
=====================

Overview
--------

.. include:: ../README.rst
:start-line: 3
:start-line: 5


.. include:: ./development.rst
Table of Content
----------------

.. toctree::
:hidden:
:maxdepth: 2

index
development
api
42 changes: 42 additions & 0 deletions orphanage/poll.py
Expand Up @@ -20,6 +20,13 @@

@ffi.def_extern()
def orphanage_poll_routine_callback(ptr):
"""The external callback function of CFFI.
This function invokes the :meth:`Context.trigger_callbacks` method.
:param ptr: The C pointer of context.
:returns: ``0`` for nonerror calls.
"""
ctx = callback_registry.get(ptr)
if ctx is None:
logger.debug('Context of %r is not found', ptr)
Expand All @@ -31,12 +38,17 @@ def orphanage_poll_routine_callback(ptr):


def perror(description):
"""Raises a runtime error from the specified description and ``errno``."""
errno = ffi.errno
errname = errorcode.get(errno, str(errno))
return RuntimeError('{0}: errno = {1}'.format(description, errname))


def raise_for_return_value(return_value):
"""Checks the return value from C area.
A runtime error will be raised if the return value is nonzero.
"""
if return_value == ORPHANAGE_POLL_OK:
return
elif return_value == ORPHANAGE_POLL_PT_CREATE_ERROR:
Expand All @@ -50,6 +62,25 @@ def raise_for_return_value(return_value):


class Context(object):
"""The context of orphans polling which acts as the CFFI wrapper.
.. caution:: It is dangerous to use this class directly except you are
familiar with the implementation of CPython and you know what
you are doing clearly. It is recommended to use the
:ref:`public_api` instead, for most users.
The context must be closed via :meth:`~Context.close` or the memory will
be leaked.
:param callbacks: Optional. The list of callback functions. A callback
function will be passed one parameter, the instance of
this context. Be careful, never invoking any Python
built-in and C/C++ extended functions which use the
``Py_BEGIN_ALLOW_THREADS``, such as ``os.close`` and all
methods on this context, to avoid from deadlock and other
undefined behaviors.
"""

def __init__(self, callbacks=None, suicide_instead=False):
self.callbacks = list(callbacks or [])
self.suicide_instead = suicide_instead
Expand All @@ -59,6 +90,7 @@ def __init__(self, callbacks=None, suicide_instead=False):
callback_registry[self.ptr] = self

def close(self):
"""Closes this context and release the memory from C area."""
lib.orphanage_poll_close(self.ptr)
callback_registry.pop(self.ptr, None)
self.ptr = None
Expand All @@ -69,16 +101,26 @@ def _started(self):
raise RuntimeError('context has been closed')

def start(self):
"""Starts the polling thread."""
self._started()
r = lib.orphanage_poll_start(self.ptr)
raise_for_return_value(r)

def stop(self):
"""Stops the polling thread.
Don't forget to release allocated memory by calling
:meth:`~Context.close` if you won't use it anymore.
"""
self._started()
r = lib.orphanage_poll_stop(self.ptr)
raise_for_return_value(r)

def trigger_callbacks(self):
"""Triggers the callback functions.
This method is expected to be called from C area.
"""
for callback in self.callbacks:
logger.debug('triggering callback %r on %r', callback, self)
try:
Expand Down
1 change: 1 addition & 0 deletions setup.py
Expand Up @@ -2,6 +2,7 @@


with open('README.rst') as readme:
next(readme) # Skip badges
long_description = ''.join(readme).strip()


Expand Down

0 comments on commit 95f26a2

Please sign in to comment.