1 """Implements the standard thread module, using greenthreads."""
2 from eventlet.support.six.moves import _thread as __thread
3 from eventlet.support import greenlets as greenlet, six
4 from eventlet import greenthread
5 from eventlet.semaphore import Semaphore as LockType
9 __patched__ = ['get_ident', 'start_new_thread', 'start_new', 'allocate_lock',
10 'allocate', 'exit', 'interrupt_main', 'stack_size', '_local',
13 error = __thread.error
19 # TODO this is a dummy code, reimplementing this may be needed:
20 # https://hg.python.org/cpython/file/b5e9bc4352e1/Modules/_threadmodule.c#l1203
21 return allocate_lock()
23 TIMEOUT_MAX = __thread.TIMEOUT_MAX
30 def get_ident(gr=None):
32 return id(greenlet.getcurrent())
37 def __thread_body(func, args, kwargs):
46 def start_new_thread(function, args=(), kwargs=None):
47 if (sys.version_info >= (3, 4)
48 and getattr(function, '__module__', '') == 'threading'
49 and hasattr(function, '__self__')):
50 # Since Python 3.4, threading.Thread uses an internal lock
51 # automatically released when the python thread state is deleted.
52 # With monkey patching, eventlet uses green threads without python
53 # thread state, so the lock is not automatically released.
55 # Wrap _bootstrap_inner() to release explicitly the thread state lock
56 # when the thread completes.
57 thread = function.__self__
58 bootstrap_inner = thread._bootstrap_inner
60 def wrap_bootstrap_inner():
64 # The lock can be cleared (ex: by a fork())
65 if thread._tstate_lock is not None:
66 thread._tstate_lock.release()
68 thread._bootstrap_inner = wrap_bootstrap_inner
71 g = greenthread.spawn_n(__thread_body, function, args, kwargs)
75 start_new = start_new_thread
78 def allocate_lock(*a):
82 allocate = allocate_lock
86 raise greenlet.GreenletExit
89 exit_thread = __thread.exit_thread
93 curr = greenlet.getcurrent()
94 if curr.parent and not curr.parent.dead:
95 curr.parent.throw(KeyboardInterrupt())
97 raise KeyboardInterrupt()
100 if hasattr(__thread, 'stack_size'):
101 __original_stack_size__ = __thread.stack_size
103 def stack_size(size=None):
105 return __original_stack_size__()
106 if size > __original_stack_size__():
107 return __original_stack_size__(size)
110 # not going to decrease stack_size, because otherwise other greenlets in
111 # this thread will suffer
113 from eventlet.corolocal import local as _local