Source

green380 / green380 / _thread.py

Full commit
from _thread import error, TIMEOUT_MAX
from . import _core

def start_new_thread(fiber, args=(), kwargs=None):
    if kwargs is None:
        kwargs = {}
    return _core.spawn(fiber, *args, **kwargs)

def get_ident():
    assert _core.current is not None
    return _core.current


class allocate_lock:

    def __init__(self):
        self._locked = False
        self._owner = None
        self._waiters = []

    def __enter__(self):
        assert self._owner is _core.current
        return self

    def __exit__(self, *args):
        self.release()

    def __iter__(self):
        yield from self.acquire()
        return self

    def _is_owned(self):
        return self._owner is _core.current

    def acquire(self, blocking=True, timeout=-1):
        if not self._locked:
            self._locked = True
            self._owner = _core.current
            return True
        if blocking:
            if timeout == -1:
                timeout = None
            elif timeout < 0:
                raise ValueError( "timeout value must be strictly positive")
            elif timeout > TIMEOUT_MAX:
                raise OverflowError("timeout value is too large")
        else:
            if timeout != -1:
                raise ValueError("can't specify a timeout for a non-blocking call")
            timeout = 0
        self._waiters.append(get_ident())
        acquired = yield from _core.timeout_multiplex(None, timeout)
        if not acquired:
            self._waiters.remove(_core.current)
        assert self._locked
        return acquired

    def release(self):
        if not self._locked:
            raise RuntimeError("can't released unlocked lock")
        if self._waiters:
            w = self._waiters.pop()
            self._owner = w
            w.send(True)
        else:
            self._locked = False
            self._owner = None