Commit c75efbec authored by Jason Madden's avatar Jason Madden

Documentation for LoopExit [skip ci]

parent 5da86fd5
......@@ -11,3 +11,5 @@
:undoc-members:
.. autoclass:: Waiter
.. autoclass:: LoopExit
......@@ -14,7 +14,7 @@ and let the others run.
socket). The results of attempting to use the socket in
another thread (for example, passing it to the
threadpool) are not defined (but one common outcome is a
``LoopExit`` exception).
:exc:`~gevent.hub.LoopExit` exception).
For convenience, exceptions (like :class:`error <socket.error>` and
:class:`timeout <socket.timeout>`) as well as the constants from the
......@@ -52,7 +52,9 @@ functions not commonly used by many programs.
.. note:: These use the underlying libev ``io`` watchers, which means
that they share the same implementation limits. For example,
on some platforms they can be used with more than just
sockets, while on others the applicability is more limited.
sockets, while on others the applicability is more limited
(POSIX platforms like Linux and OS X can use pipes and fifos
but Windows is limited to sockets).
.. autofunction:: gevent.socket.wait_read
.. autofunction:: gevent.socket.wait_write
......
......@@ -87,6 +87,23 @@ _NONE = _NONE()
class LoopExit(Exception):
"""
Exception thrown when the hub finishes running.
In a normal application, this is never thrown or caught
explicitly. The internal implementation of functions like
:func:`join` and :func:`joinall` may catch it, but user code
generally should not.
.. caution::
Errors in application programming can also lead to this exception being
raised. Some examples include (but are not limited too):
- greenlets deadlocking on a lock;
- using a socket or other gevent object with native thread
affinity from a different thread
"""
pass
......
......@@ -333,6 +333,7 @@ class TestCase(TestCaseMetaClass("NewBase", (BaseTestCase,), {})):
__timeout__ = 1 if not RUNNING_ON_CI else 5
switch_expected = 'default'
error_fatal = True
close_on_teardown = ()
def run(self, *args, **kwargs):
if self.switch_expected == 'default':
......@@ -345,6 +346,21 @@ class TestCase(TestCaseMetaClass("NewBase", (BaseTestCase,), {})):
if hasattr(self, 'cleanup'):
self.cleanup()
self._error = self._none
for x in self.close_on_teardown:
try:
x.close()
except Exception:
pass
try:
del self.close_on_teardown
except AttributeError:
pass
def _close_on_teardown(self, resource):
if 'close_on_teardown' not in self.__dict__:
self.close_on_teardown = []
self.close_on_teardown.append(resource)
return resource
@property
def testname(self):
......
......@@ -58,9 +58,11 @@ class TestTCP(greentest.TestCase):
pass
del self.listener
def create_connection(self):
def create_connection(self, port=None, timeout=None):
sock = socket.socket()
sock.connect(('127.0.0.1', self.port))
sock.connect(('127.0.0.1', port or self.port))
if timeout is not None:
sock.settimeout(timeout)
return sock
def _test_sendall(self, data):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment