1
"""Implements the standard threading module, using greenthreads."""
1
2
from eventlet import patcher
2
3
from eventlet.green import thread
3
4
from eventlet.green import time
5
from eventlet.support import greenlets as greenlet
5
7
__patched__ = ['_start_new_thread', '_allocate_lock', '_get_ident', '_sleep',
6
'local', 'stack_size', 'Lock']
8
'local', 'stack_size', 'Lock', 'currentThread',
11
__orig_threading = patcher.original('threading')
12
__threadlocal = __orig_threading.local()
8
15
patcher.inject('threading',
24
class _GreenThread(object):
25
"""Wrapper for GreenThread objects to provide Thread-like attributes
27
def __init__(self, g):
30
self._name = 'GreenThread-%d' % _count
34
return '<_GreenThread(%s, %r)>' % (self._name, self._g)
51
# Some third-party packages (lockfile) will try to patch the
52
# threading.Thread class with a get_name attribute if it doesn't
53
# exist. Since we might return Thread objects from the original
54
# threading package that won't get patched, let's make sure each
55
# individual object gets patched too our patched threading.Thread
56
# class has been patched. This is why monkey patching can be bad...
59
__threading = __import__('threading')
61
if (hasattr(__threading.Thread, 'get_name') and
62
not hasattr(t, 'get_name')):
63
t.get_name = t.getName
68
g = greenlet.getcurrent()
70
# Not currently in a greenthread, fall back to standard function
71
return _fixup_thread(__orig_threading.current_thread())
74
active = __threadlocal.active
75
except AttributeError:
76
active = __threadlocal.active = {}
81
# Add green thread to active if we can clean it up on exit
86
except AttributeError:
87
# Not a GreenThread type, so there's no way to hook into
88
# the green thread exiting. Fall back to the standard
90
t = _fixup_thread(__orig_threading.current_thread())
92
t = active[id(g)] = _GreenThread(g)
96
currentThread = current_thread