~ubuntu-branches/ubuntu/trusty/python-eventlet/trusty-proposed

« back to all changes in this revision

Viewing changes to eventlet/green/threading.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2012-03-02 08:57:57 UTC
  • Revision ID: package-import@ubuntu.com-20120302085757-kpasohz8nme655o1
Tags: 0.9.16-1ubuntu2
debian/patches/eventlet-leak.patch: Fixes memory leak in nova. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
4
6
 
5
7
__patched__ = ['_start_new_thread', '_allocate_lock', '_get_ident', '_sleep',
6
 
               'local', 'stack_size', 'Lock']
 
8
               'local', 'stack_size', 'Lock', 'currentThread',
 
9
               'current_thread']
 
10
 
 
11
__orig_threading = patcher.original('threading')
 
12
__threadlocal = __orig_threading.local()
 
13
 
7
14
 
8
15
patcher.inject('threading',
9
16
    globals(),
11
18
    ('time', time))
12
19
 
13
20
del patcher
 
21
 
 
22
 
 
23
_count = 1
 
24
class _GreenThread(object):
 
25
    """Wrapper for GreenThread objects to provide Thread-like attributes
 
26
    and methods"""
 
27
    def __init__(self, g):
 
28
        global _count
 
29
        self._g = g
 
30
        self._name = 'GreenThread-%d' % _count
 
31
        _count += 1
 
32
 
 
33
    def __repr__(self):
 
34
        return '<_GreenThread(%s, %r)>' % (self._name, self._g)
 
35
 
 
36
    @property
 
37
    def name(self):
 
38
        return self._name
 
39
 
 
40
    def getName(self):
 
41
        return self.name
 
42
    get_name = getName
 
43
 
 
44
    def join(self):
 
45
        return self._g.wait()
 
46
 
 
47
 
 
48
__threading = None
 
49
 
 
50
def _fixup_thread(t):
 
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...
 
57
    global __threading
 
58
    if not __threading:
 
59
        __threading = __import__('threading')
 
60
 
 
61
    if (hasattr(__threading.Thread, 'get_name') and
 
62
        not hasattr(t, 'get_name')):
 
63
        t.get_name = t.getName
 
64
    return t
 
65
 
 
66
 
 
67
def current_thread():
 
68
    g = greenlet.getcurrent()
 
69
    if not g:
 
70
        # Not currently in a greenthread, fall back to standard function
 
71
        return _fixup_thread(__orig_threading.current_thread())
 
72
 
 
73
    try:
 
74
        active = __threadlocal.active
 
75
    except AttributeError:
 
76
        active = __threadlocal.active = {}
 
77
    
 
78
    try:
 
79
        t = active[id(g)]
 
80
    except KeyError:
 
81
        # Add green thread to active if we can clean it up on exit
 
82
        def cleanup(g):
 
83
            del active[id(g)]
 
84
        try:
 
85
            g.link(cleanup)
 
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
 
89
            # function then.
 
90
            t = _fixup_thread(__orig_threading.current_thread())
 
91
        else:
 
92
            t = active[id(g)] = _GreenThread(g)
 
93
 
 
94
    return t
 
95
 
 
96
currentThread = current_thread