Add python-eventlet 0.16.1
[packages/trusty/python-eventlet.git] / eventlet / eventlet / green / thread.py
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
6
7
8 __patched__ = ['get_ident', 'start_new_thread', 'start_new', 'allocate_lock',
9                'allocate', 'exit', 'interrupt_main', 'stack_size', '_local',
10                'LockType', '_count']
11
12 error = __thread.error
13 __threadcount = 0
14
15
16 if six.PY3:
17     def _set_sentinel():
18         # TODO this is a dummy code, reimplementing this may be needed:
19         # https://hg.python.org/cpython/file/b5e9bc4352e1/Modules/_threadmodule.c#l1203
20         return allocate_lock()
21
22     TIMEOUT_MAX = __thread.TIMEOUT_MAX
23
24
25 def _count():
26     return __threadcount
27
28
29 def get_ident(gr=None):
30     if gr is None:
31         return id(greenlet.getcurrent())
32     else:
33         return id(gr)
34
35
36 def __thread_body(func, args, kwargs):
37     global __threadcount
38     __threadcount += 1
39     try:
40         func(*args, **kwargs)
41     finally:
42         __threadcount -= 1
43
44
45 def start_new_thread(function, args=(), kwargs=None):
46     kwargs = kwargs or {}
47     g = greenthread.spawn_n(__thread_body, function, args, kwargs)
48     return get_ident(g)
49
50
51 start_new = start_new_thread
52
53
54 def allocate_lock(*a):
55     return LockType(1)
56
57
58 allocate = allocate_lock
59
60
61 def exit():
62     raise greenlet.GreenletExit
63
64
65 exit_thread = __thread.exit_thread
66
67
68 def interrupt_main():
69     curr = greenlet.getcurrent()
70     if curr.parent and not curr.parent.dead:
71         curr.parent.throw(KeyboardInterrupt())
72     else:
73         raise KeyboardInterrupt()
74
75
76 if hasattr(__thread, 'stack_size'):
77     __original_stack_size__ = __thread.stack_size
78
79     def stack_size(size=None):
80         if size is None:
81             return __original_stack_size__()
82         if size > __original_stack_size__():
83             return __original_stack_size__(size)
84         else:
85             pass
86             # not going to decrease stack_size, because otherwise other greenlets in
87             # this thread will suffer
88
89 from eventlet.corolocal import local as _local