This file is indexed.

/usr/lib/python2.7/dist-packages/gevent/threading.py is in python-gevent 1.1.0-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
from __future__ import absolute_import


__implements__ = ['local',
                  '_start_new_thread',
                  '_allocate_lock',
                  'Lock',
                  '_get_ident',
                  '_sleep',
                  '_DummyThread']


import threading as __threading__
_DummyThread_ = __threading__._DummyThread
from gevent.local import local
from gevent.thread import start_new_thread as _start_new_thread, allocate_lock as _allocate_lock, get_ident as _get_ident
from gevent.hub import sleep as _sleep, getcurrent, PYPY
Lock = _allocate_lock


def _cleanup(g):
    __threading__._active.pop(id(g), None)


class _DummyThread(_DummyThread_):
    # We avoid calling the superclass constructor. This makes us about
    # twice as fast (1.16 vs 0.68usec on PyPy, 29.3 vs 17.7usec on
    # CPython 2.7), and has the important effect of avoiding
    # allocation and then immediate deletion of _Thread__block, a
    # lock. This is especially important on PyPy where locks go
    # through the cpyext API and Cython, which is known to be slow and
    # potentially buggy (e.g.,
    # https://bitbucket.org/pypy/pypy/issues/2149/memory-leak-for-python-subclass-of-cpyext#comment-22347393)

    # These objects are constructed quite frequently in some cases, so
    # the optimization matters: for example, in gunicorn, which uses
    # pywsgi.WSGIServer, every request is handled in a new greenlet,
    # and every request uses a logging.Logger to write the access log,
    # and every call to a log method captures the current thread (by
    # default).
    #
    # (Obviously we have to duplicate the effects of the constructor,
    # at least for external state purposes, which is potentially
    # slightly fragile.)

    # For the same reason, instances of this class will cleanup their own entry
    # in ``threading._active``

    # Capture the static things as class vars to save on memory/
    # construction time.
    # In Py2, they're all private; in Py3, they become protected
    _Thread__stopped = _is_stopped = _stopped = False
    _Thread__initialized = _initialized = True
    _Thread__daemonic = _daemonic = True
    _Thread__args = _args = ()
    _Thread__kwargs = _kwargs = None
    _Thread__target = _target = None
    _Thread_ident = _ident = None
    _Thread__started = _started = __threading__.Event()
    _Thread__started.set()
    _tstate_lock = None

    def __init__(self):
        #_DummyThread_.__init__(self)

        # It'd be nice to use a pattern like "greenlet-%d", but maybe somebody out
        # there is checking thread names...
        self._name = self._Thread__name = __threading__._newname("DummyThread-%d")
        self._set_ident()

        __threading__._active[_get_ident()] = self
        g = getcurrent()
        rawlink = getattr(g, 'rawlink', None)
        if rawlink is not None:
            rawlink(_cleanup)

    def _Thread__stop(self):
        pass

    _stop = _Thread__stop # py3

    def _wait_for_tstate_lock(self, *args, **kwargs):
        pass

# Make sure the MainThread can be found by our current greenlet ID,
# otherwise we get a new DummyThread, which cannot be joined.
# Fixes tests in test_threading_2 under PyPy, and generally makes things nicer
# when gevent.threading is imported before monkey patching or not at all
# XXX: This assumes that the import is happening in the "main" greenlet
if _get_ident() not in __threading__._active and len(__threading__._active) == 1:
    k, v = next(iter(__threading__._active.items()))
    del __threading__._active[k]
    v._Thread__ident = _get_ident()
    __threading__._active[_get_ident()] = v
    del k
    del v

    # Avoid printing an error on shutdown trying to remove the thread entry
    # we just replaced if we're not fully monkey patched in
    # XXX: This causes a hang on PyPy for some unknown reason (as soon as class _active
    # defines __delitem__, shutdown hangs. Maybe due to something with the GC?
    # XXX: This may be fixed in 2.6.1+
    if not PYPY:
        _MAIN_THREAD = __threading__._get_ident() if hasattr(__threading__, '_get_ident') else __threading__.get_ident()

        class _active(dict):
            def __delitem__(self, k):
                if k == _MAIN_THREAD and k not in self:
                    return
                dict.__delitem__(self, k)

        __threading__._active = _active(__threading__._active)


import sys
if sys.version_info[:2] >= (3, 4):
    # XXX: Issue 18808 breaks us on Python 3.4.
    # Thread objects now expect a callback from the interpreter itself
    # (threadmodule.c:release_sentinel). Because this never happens
    # when a greenlet exits, join() and friends will block forever.
    # The solution below involves capturing the greenlet when it is
    # started and deferring the known broken methods to it.

    class Thread(__threading__.Thread):
        _greenlet = None

        def is_alive(self):
            return bool(self._greenlet)

        isAlive = is_alive

        def _set_tstate_lock(self):
            self._greenlet = getcurrent()

        def run(self):
            try:
                super(Thread, self).run()
            finally:
                # avoid ref cycles, but keep in __dict__ so we can
                # distinguish the started/never-started case
                self._greenlet = None
                self._stop() # mark as finished

        def join(self, timeout=None):
            if '_greenlet' not in self.__dict__:
                raise RuntimeError("Cannot join an inactive thread")
            if self._greenlet is None:
                return
            self._greenlet.join(timeout=timeout)

        def _wait_for_tstate_lock(self, *args, **kwargs):
            raise NotImplementedError()

    __implements__.append('Thread')

    # The main thread is patched up with more care in monkey.py
    #t = __threading__.current_thread()
    #if isinstance(t, __threading__.Thread):
    #    t.__class__ = Thread
    #    t._greenlet = getcurrent()

if sys.version_info[:2] >= (3, 3):
    __implements__.remove('_get_ident')
    __implements__.append('get_ident')
    get_ident = _get_ident
    __implements__.remove('_sleep')

    # Python 3 changed the implementation of threading.RLock
    # Previously it was a factory function around threading._RLock
    # which in turn used _allocate_lock. Now, it wants to use
    # threading._CRLock, which is imported from _thread.RLock and as such
    # is implemented in C. So it bypasses our _allocate_lock function.
    # Fortunately they left the Python fallback in place
    assert hasattr(__threading__, '_CRLock'), "Unsupported Python version"
    _CRLock = None
    __implements__.append('_CRLock')