diff options
author | James Taylor <user234683@users.noreply.github.com> | 2018-07-12 23:40:30 -0700 |
---|---|---|
committer | James Taylor <user234683@users.noreply.github.com> | 2018-07-12 23:41:07 -0700 |
commit | c3b9f8c4582882cd1f768b0727eca75475bb4f94 (patch) | |
tree | 5b4a1c693fd5b7416f1d5a75862e633502e77ca7 /python/gevent/thread.py | |
parent | fe9fe8257740529f5880693992e4eeca35c7ea3e (diff) | |
download | yt-local-c3b9f8c4582882cd1f768b0727eca75475bb4f94.tar.lz yt-local-c3b9f8c4582882cd1f768b0727eca75475bb4f94.tar.xz yt-local-c3b9f8c4582882cd1f768b0727eca75475bb4f94.zip |
track embedded python distribution
Diffstat (limited to 'python/gevent/thread.py')
-rw-r--r-- | python/gevent/thread.py | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/python/gevent/thread.py b/python/gevent/thread.py new file mode 100644 index 0000000..0a1af38 --- /dev/null +++ b/python/gevent/thread.py @@ -0,0 +1,115 @@ +""" +Implementation of the standard :mod:`thread` module that spawns greenlets. + +.. note:: + + This module is a helper for :mod:`gevent.monkey` and is not + intended to be used directly. For spawning greenlets in your + applications, prefer higher level constructs like + :class:`gevent.Greenlet` class or :func:`gevent.spawn`. +""" +from __future__ import absolute_import +import sys + +__implements__ = ['allocate_lock', + 'get_ident', + 'exit', + 'LockType', + 'stack_size', + 'start_new_thread', + '_local'] + +__imports__ = ['error'] +if sys.version_info[0] <= 2: + import thread as __thread__ # pylint:disable=import-error +else: + import _thread as __thread__ # pylint:disable=import-error + __target__ = '_thread' + __imports__ += ['RLock', + 'TIMEOUT_MAX', + 'allocate', + 'exit_thread', + 'interrupt_main', + 'start_new'] +error = __thread__.error +from gevent._compat import PY3 +from gevent._compat import PYPY +from gevent._util import copy_globals +from gevent.hub import getcurrent, GreenletExit +from gevent.greenlet import Greenlet +from gevent.lock import BoundedSemaphore +from gevent.local import local as _local + + +def get_ident(gr=None): + if gr is None: + gr = getcurrent() + return id(gr) + + +def start_new_thread(function, args=(), kwargs=None): + if kwargs is not None: + greenlet = Greenlet.spawn(function, *args, **kwargs) + else: + greenlet = Greenlet.spawn(function, *args) + return get_ident(greenlet) + + +class LockType(BoundedSemaphore): + # Change the ValueError into the appropriate thread error + # and any other API changes we need to make to match behaviour + _OVER_RELEASE_ERROR = __thread__.error + + if PYPY and PY3: + _OVER_RELEASE_ERROR = RuntimeError + + if PY3: + _TIMEOUT_MAX = __thread__.TIMEOUT_MAX # python 2: pylint:disable=no-member + + def acquire(self, blocking=True, timeout=-1): + # Transform the default -1 argument into the None that our + # semaphore implementation expects, and raise the same error + # the stdlib implementation does. + if timeout == -1: + timeout = None + if not blocking and timeout is not None: + raise ValueError("can't specify a timeout for a non-blocking call") + if timeout is not None: + if timeout < 0: + # in C: if(timeout < 0 && timeout != -1) + raise ValueError("timeout value must be strictly positive") + if timeout > self._TIMEOUT_MAX: + raise OverflowError('timeout value is too large') + + return BoundedSemaphore.acquire(self, blocking, timeout) + +allocate_lock = LockType + + +def exit(): + raise GreenletExit + + +if hasattr(__thread__, 'stack_size'): + _original_stack_size = __thread__.stack_size + + def stack_size(size=None): + if size is None: + return _original_stack_size() + if size > _original_stack_size(): + return _original_stack_size(size) + else: + pass + # not going to decrease stack_size, because otherwise other greenlets in this thread will suffer +else: + __implements__.remove('stack_size') + +__imports__ = copy_globals(__thread__, globals(), + only_names=__imports__, + ignore_missing_names=True) + +__all__ = __implements__ + __imports__ +__all__.remove('_local') + +# XXX interrupt_main +# XXX _count() |