codekingpro/portable-devtools
114k
1"""Implements the standard thread module, using greenthreads."""2from six.moves import _thread as __thread3import six4from eventlet.support import greenlets as greenlet5from eventlet import greenthread6from eventlet.lock import Lock7import sys8 9 10__patched__ = ['get_ident', 'start_new_thread', 'start_new', 'allocate_lock',11 'allocate', 'exit', 'interrupt_main', 'stack_size', '_local',12 'LockType', 'Lock', '_count']13 14error = __thread.error15LockType = Lock16__threadcount = 017 18if hasattr(__thread, "_is_main_interpreter"):19 _is_main_interpreter = __thread._is_main_interpreter20 21if six.PY3:22 def _set_sentinel():23 # TODO this is a dummy code, reimplementing this may be needed:24 # https://hg.python.org/cpython/file/b5e9bc4352e1/Modules/_threadmodule.c#l120325 return allocate_lock()26 27 TIMEOUT_MAX = __thread.TIMEOUT_MAX28 29 30def _count():31 return __threadcount32 33 34def get_ident(gr=None):35 if gr is None:36 return id(greenlet.getcurrent())37 else:38 return id(gr)39 40 41def __thread_body(func, args, kwargs):42 global __threadcount43 __threadcount += 144 try:45 func(*args, **kwargs)46 finally:47 __threadcount -= 148 49 50def start_new_thread(function, args=(), kwargs=None):51 if (sys.version_info >= (3, 4)52 and getattr(function, '__module__', '') == 'threading'53 and hasattr(function, '__self__')):54 # Since Python 3.4, threading.Thread uses an internal lock55 # automatically released when the python thread state is deleted.56 # With monkey patching, eventlet uses green threads without python57 # thread state, so the lock is not automatically released.58 #59 # Wrap _bootstrap_inner() to release explicitly the thread state lock60 # when the thread completes.61 thread = function.__self__62 bootstrap_inner = thread._bootstrap_inner63 64 def wrap_bootstrap_inner():65 try:66 bootstrap_inner()67 finally:68 # The lock can be cleared (ex: by a fork())69 if thread._tstate_lock is not None:70 thread._tstate_lock.release()71 72 thread._bootstrap_inner = wrap_bootstrap_inner73 74 kwargs = kwargs or {}75 g = greenthread.spawn_n(__thread_body, function, args, kwargs)76 return get_ident(g)77 78 79start_new = start_new_thread80 81 82def allocate_lock(*a):83 return LockType(1)84 85 86allocate = allocate_lock87 88 89def exit():90 raise greenlet.GreenletExit91 92 93exit_thread = __thread.exit_thread94 95 96def interrupt_main():97 curr = greenlet.getcurrent()98 if curr.parent and not curr.parent.dead:99 curr.parent.throw(KeyboardInterrupt())100 else:101 raise KeyboardInterrupt()102 103 104if hasattr(__thread, 'stack_size'):105 __original_stack_size__ = __thread.stack_size106 107 def stack_size(size=None):108 if size is None:109 return __original_stack_size__()110 if size > __original_stack_size__():111 return __original_stack_size__(size)112 else:113 pass114 # not going to decrease stack_size, because otherwise other greenlets in115 # this thread will suffer116 117from eventlet.corolocal import local as _local118 119if hasattr(__thread, 'daemon_threads_allowed'):120 daemon_threads_allowed = __thread.daemon_threads_allowed121 