def semlock_acquire(self, space, block, w_timeout):
        if not block:
            full_msecs = 0
        elif space.is_none(w_timeout):
            full_msecs = rwin32.INFINITE
        else:
            timeout = space.float_w(w_timeout)
            timeout *= 1000.0
            if timeout < 0.0:
                timeout = 0.0
            elif timeout >= 0.5 * rwin32.INFINITE:  # 25 days
                raise oefmt(space.w_OverflowError, "timeout is too large")
            full_msecs = r_uint(int(timeout + 0.5))

        # check whether we can acquire without blocking
        res = rwin32.WaitForSingleObject(self.handle, 0)

        if res != rwin32.WAIT_TIMEOUT:
            self.last_tid = rthread.get_ident()
            self.count += 1
            return True

        msecs = full_msecs
        start = _GetTickCount()

        while True:
            from pypy.module.time.interp_time import State
            interrupt_event = space.fromcache(State).get_interrupt_event()
            handles = [self.handle, interrupt_event]

            # do the wait
            rwin32.ResetEvent(interrupt_event)
            res = rwin32.WaitForMultipleObjects(handles, timeout=msecs)

            if res != rwin32.WAIT_OBJECT_0 + 1:
                break

            # got SIGINT so give signal handler a chance to run
            time.sleep(0.001)

            # if this is main thread let KeyboardInterrupt be raised
            _check_signals(space)

            # recalculate timeout
            if msecs != rwin32.INFINITE:
                ticks = _GetTickCount()
                if r_uint(ticks - start) >= full_msecs:
                    return False
                msecs = full_msecs - r_uint(ticks - start)

        # handle result
        if res != rwin32.WAIT_TIMEOUT:
            self.last_tid = rthread.get_ident()
            self.count += 1
            return True
        return False
Пример #2
0
 def f(num):
     rthread.get_ident()  # register TLOFS_thread_ident
     code = MyCode("py:x:foo:3")
     rvmprof.register_code(code, get_name)
     fd = os.open(tmpfilename, os.O_WRONLY | os.O_CREAT, 0666)
     period = 0.0001
     rvmprof.enable(fd, period)
     res = main(code, num)
     #assert res == 499999500000
     rvmprof.disable()
     os.close(fd)
     return 0
Пример #3
0
 def f(num):
     rthread.get_ident() # register TLOFS_thread_ident
     code = MyCode("py:x:foo:3")
     rvmprof.register_code(code, get_name)
     fd = os.open(tmpfilename, os.O_WRONLY | os.O_CREAT, 0666)
     period = 0.0001
     rvmprof.enable(fd, period)
     res = main(code, num)
     #assert res == 499999500000
     rvmprof.disable()
     os.close(fd)
     return 0
Пример #4
0
    def acquire_w(self, space, blocking=True, timeout=-1.0):
        """Lock the lock.  `blocking` indicates whether we should wait
        for the lock to be available or not.  If `blocking` is False
        and another thread holds the lock, the method will return False
        immediately.  If `blocking` is True and another thread holds
        the lock, the method will wait for the lock to be released,
        take it and then return True.
        (note: the blocking operation is not interruptible.)

        In all other cases, the method will return True immediately.
        Precisely, if the current thread already holds the lock, its
        internal counter is simply incremented. If nobody holds the lock,
        the lock is taken and its internal counter initialized to 1."""
        microseconds = parse_acquire_args(space, blocking, timeout)
        tid = rthread.get_ident()
        if self.rlock_count > 0 and tid == self.rlock_owner:
            try:
                self.rlock_count = ovfcheck(self.rlock_count + 1)
            except OverflowError:
                raise oefmt(space.w_OverflowError,
                            "internal lock count overflowed")
            return space.w_True

        r = True
        if self.rlock_count > 0 or not self.lock.acquire(False):
            if not blocking:
                return space.w_False
            r = acquire_timed(space, self.lock, microseconds)
            r = (r == RPY_LOCK_ACQUIRED)
        if r:
            assert self.rlock_count == 0
            self.rlock_owner = tid
            self.rlock_count = 1

        return space.newbool(r)
Пример #5
0
    def acquire_w(self, space, blocking=1):
        """Acquire a lock, blocking or non-blocking.

        When invoked without arguments: if this thread already owns the lock,
        increment the recursion level by one, and return immediately. Otherwise,
        if another thread owns the lock, block until the lock is unlocked. Once
        the lock is unlocked (not owned by any thread), then grab ownership, set
        the recursion level to one, and return. If more than one thread is
        blocked waiting until the lock is unlocked, only one at a time will be
        able to grab ownership of the lock. There is no return value in this
        case.

        When invoked with the blocking argument set to true, do the same thing
        as when called without arguments, and return true.

        When invoked with the blocking argument set to false, do not block. If a
        call without an argument would block, return false immediately;
        otherwise, do the same thing as when called without arguments, and
        return true.

        """
        tid = rthread.get_ident()
        if tid == self.rlock_owner:
            try:
                self.rlock_count = ovfcheck(self.rlock_count + 1)
            except OverflowError:
                raise oefmt(space.w_OverflowError,
                            "internal lock count overflowed")
            return space.w_True

        rc = self.lock.acquire(blocking != 0)
        if rc:
            self.rlock_owner = tid
            self.rlock_count = 1
        return space.newbool(rc)
Пример #6
0
 def f():
     state.data = []
     state.datalen1 = 0
     state.datalen2 = 0
     state.datalen3 = 0
     state.datalen4 = 0
     state.threadlocals = my_gil_threadlocals
     state.threadlocals.setup_threads(space)
     subident = thread.start_new_thread(bootstrap, ())
     mainident = thread.get_ident()
     runme(True)
     still_waiting = 3000
     while len(state.data) < 2 * N:
         debug_print(len(state.data))
         if not still_waiting:
             raise ValueError("time out")
         still_waiting -= 1
         if not we_are_translated(): gil.before_external_call()
         time.sleep(0.01)
         if not we_are_translated(): gil.after_external_call()
     debug_print("leaving!")
     i1 = i2 = 0
     for tid, i in state.data:
         if tid == mainident:
             assert i == i1
             i1 += 1
         elif tid == subident:
             assert i == i2
             i2 += 1
         else:
             assert 0
     assert i1 == N + skew
     assert i2 == N - skew
     return len(state.data)
Пример #7
0
 def f():
     state.data = []
     state.datalen1 = 0
     state.datalen2 = 0
     state.datalen3 = 0
     state.datalen4 = 0
     state.threadlocals = my_gil_threadlocals
     state.threadlocals.setup_threads(space)
     subident = thread.start_new_thread(bootstrap, ())
     mainident = thread.get_ident()
     runme(True)
     still_waiting = 3000
     while len(state.data) < 2*N:
         debug_print(len(state.data))
         if not still_waiting:
             llop.debug_print(lltype.Void, "timeout. progress: "
                              "%d of 2*N (= %f%%)" % \
                              (len(state.data), 2*N, 100*len(state.data)/(2.0*N)))
             raise ValueError("time out")
         still_waiting -= 1
         if not we_are_translated(): rgil.release()
         time.sleep(0.1)
         if not we_are_translated(): rgil.acquire()
     debug_print("leaving!")
     i1 = i2 = 0
     for tid, i in state.data:
         if tid == mainident:
             assert i == i1; i1 += 1
         elif tid == subident:
             assert i == i2; i2 += 1
         else:
             assert 0
     assert i1 == N + skew
     assert i2 == N - skew
     return len(state.data)
Пример #8
0
 def f():
     state.data = []
     state.datalen1 = 0
     state.datalen2 = 0
     state.datalen3 = 0
     state.datalen4 = 0
     state.threadlocals = gil.GILThreadLocals()
     state.threadlocals.setup_threads(space)
     thread.gc_thread_prepare()
     subident = thread.start_new_thread(bootstrap, ())
     mainident = thread.get_ident()
     runme(True)
     still_waiting = 3000
     while len(state.data) < 2*N:
         debug_print(len(state.data))
         if not still_waiting:
             raise ValueError("time out")
         still_waiting -= 1
         if not we_are_translated(): gil.before_external_call()
         time.sleep(0.01)
         if not we_are_translated(): gil.after_external_call()
     debug_print("leaving!")
     i1 = i2 = 0
     for tid, i in state.data:
         if tid == mainident:
             assert i == i1; i1 += 1
         elif tid == subident:
             assert i == i2; i2 += 1
         else:
             assert 0
     assert i1 == N + skew
     assert i2 == N - skew
     return len(state.data)
Пример #9
0
 def is_owned_w(self, space):
     """For internal use by `threading.Condition`."""
     tid = rthread.get_ident()
     if self.rlock_count > 0 and self.rlock_owner == tid:
         return space.w_True
     else:
         return space.w_False
Пример #10
0
 def _set_ec(self, ec, register_in_valuedict=True):
     ident = rthread.get_ident()
     if self._mainthreadident == 0 or self._mainthreadident == ident:
         ec._signals_enabled = 1  # the main thread is enabled
         self._mainthreadident = ident
     if register_in_valuedict:
         self._valuedict[ident] = ec
     self.raw_thread_local.set(ec)
Пример #11
0
 def _set_ec(self, ec, register_in_valuedict=True):
     ident = rthread.get_ident()
     if self._mainthreadident == 0 or self._mainthreadident == ident:
         ec._signals_enabled = 1    # the main thread is enabled
         self._mainthreadident = ident
     if register_in_valuedict:
         self._valuedict[ident] = ec
     self.raw_thread_local.set(ec)
Пример #12
0
 def run(space, w_callable, args):
     try:
         space.call_args(w_callable, args)
     except OperationError, e:
         if not e.match(space, space.w_SystemExit):
             ident = rthread.get_ident()
             where = 'thread %d started by ' % ident
             e.write_unraisable(space, where, w_callable, with_traceback=True)
         e.clear(space)
Пример #13
0
def main(argv=[]):
    rthread.get_ident() # force TLOFS_thread_ident
    if NonConstant(False):
        # Hack to give os.open() the correct annotation
        os.open('foo', 1, 1)
    code1 = MyCode(6500)
    fd = os.open(PROF_FILE, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0666)
    rvmprof.enable(fd, 0.01)
    #
    code2 = MyCode(9100)
    stop = time.time() + 1
    while time.time() < stop:
        interpret(code1)
        interpret(code2)
    #
    rvmprof.disable()
    os.close(fd)
    return 0
Пример #14
0
 def _set_ec(self, ec):
     ident = rthread.get_ident()
     if self._mainthreadident == 0 or self._mainthreadident == ident:
         ec._signals_enabled = 1  # the main thread is enabled
         self._mainthreadident = ident
     self._valuedict[ident] = ec
     # This logic relies on hacks and _make_sure_does_not_move().
     # It only works because we keep the 'ec' alive in '_valuedict' too.
     self.raw_thread_local.set(ec)
Пример #15
0
 def _set_ec(self, ec):
     ident = rthread.get_ident()
     if self._mainthreadident == 0 or self._mainthreadident == ident:
         ec._signals_enabled = 1    # the main thread is enabled
         self._mainthreadident = ident
     self._valuedict[ident] = ec
     # This logic relies on hacks and _make_sure_does_not_move().
     # It only works because we keep the 'ec' alive in '_valuedict' too.
     self.raw_thread_local.set(ec)
Пример #16
0
 def reinit_threads(self, space):
     "Called in the child process after a fork()"
     ident = rthread.get_ident()
     ec = self.getvalue()
     if ident != self._mainthreadident:
         ec._signals_enabled += 1
     self._cleanup_()
     self._mainthreadident = ident
     self.setvalue(ec)
Пример #17
0
def main(argv=[]):
    rthread.get_ident()  # force TLOFS_thread_ident
    if NonConstant(False):
        # Hack to give os.open() the correct annotation
        os.open('foo', 1, 1)
    code1 = MyCode(6500)
    fd = os.open(PROF_FILE, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0666)
    rvmprof.enable(fd, 0.01)
    #
    code2 = MyCode(9100)
    stop = time.time() + 1
    while time.time() < stop:
        interpret(code1)
        interpret(code2)
    #
    rvmprof.disable()
    os.close(fd)
    return 0
Пример #18
0
def get_ident(space):
    """Return a non-zero integer that uniquely identifies the current thread
amongst other threads that exist simultaneously.
This may be used to identify per-thread resources.
Even though on some platforms threads identities may appear to be
allocated consecutive numbers starting at 1, this behavior should not
be relied upon, and the number should be seen purely as a magic cookie.
A thread's identity may be reused for another thread after it exits."""
    ident = rthread.get_ident()
    return space.newint(ident)
Пример #19
0
def get_ident(space):
    """Return a non-zero integer that uniquely identifies the current thread
amongst other threads that exist simultaneously.
This may be used to identify per-thread resources.
Even though on some platforms threads identities may appear to be
allocated consecutive numbers starting at 1, this behavior should not
be relied upon, and the number should be seen purely as a magic cookie.
A thread's identity may be reused for another thread after it exits."""
    ident = rthread.get_ident()
    return space.wrap(ident)
Пример #20
0
 def getvalue(self):
     ident = rthread.get_ident()
     if ident == self._mostrecentkey:
         result = self._mostrecentvalue
     else:
         value = self._valuedict.get(ident, None)
         # slow path: update the minicache
         self._mostrecentkey = ident
         self._mostrecentvalue = value
         result = value
     return result
Пример #21
0
 def run(space, w_callable, args):
     # add the ExecutionContext to space.threadlocals
     space.threadlocals.enter_thread(space)
     try:
         space.call_args(w_callable, args)
     except OperationError, e:
         if not e.match(space, space.w_SystemExit):
             ident = rthread.get_ident()
             where = 'thread %d started by ' % ident
             e.write_unraisable(space, where, w_callable, with_traceback=True)
         e.clear(space)
Пример #22
0
 def __exit__(self, *args):
     assert self.rec_level > 0
     self.rec_level -= 1
     if self.space.config.objspace.usemodules.thread:
         from rpython.rlib import rthread
         #
         tid = rthread.get_ident()
         assert tid == self.lock_owner
         if self.rec_level == 0:
             self.lock_owner = 0
             self.lock.release()
Пример #23
0
 def sleep(space, secs):
     _check_sleep_arg(space, secs)
     # as decreed by Guido, only the main thread can be
     # interrupted.
     main_thread = space.fromcache(State).main_thread
     interruptible = (main_thread == thread.get_ident())
     MAX = sys.maxint / 1000.0  # > 24 days
     while secs > MAX:
         _simple_sleep(space, MAX, interruptible)
         secs -= MAX
     _simple_sleep(space, secs, interruptible)
Пример #24
0
 def reinit_threads(self, space):
     "Called in the child process after a fork()"
     ident = rthread.get_ident()
     ec = self.get_ec()
     assert ec is not None
     old_sig = ec._signals_enabled
     if ident != self._mainthreadident:
         old_sig += 1
     self._cleanup_()
     self._mainthreadident = ident
     self._set_ec(ec)
     ec._signals_enabled = old_sig
Пример #25
0
 def reinit_threads(self, space):
     "Called in the child process after a fork()"
     ident = rthread.get_ident()
     ec = self.get_ec()
     assert ec is not None
     old_sig = ec._signals_enabled
     if ident != self._mainthreadident:
         old_sig += 1
     self._cleanup_()
     self._mainthreadident = ident
     self._set_ec(ec)
     ec._signals_enabled = old_sig
Пример #26
0
 def sleep(space, secs):
     if secs < 0:
         raise OperationError(space.w_IOError,
                              space.wrap("Invalid argument: negative time in sleep"))
     # as decreed by Guido, only the main thread can be
     # interrupted.
     main_thread = space.fromcache(State).main_thread
     interruptible = (main_thread == thread.get_ident())
     MAX = sys.maxint / 1000.0 # > 24 days
     while secs > MAX:
         _simple_sleep(space, MAX, interruptible)
         secs -= MAX
     _simple_sleep(space, secs, interruptible)
Пример #27
0
 def sleep(space, secs):
     if secs < 0:
         raise OperationError(space.w_IOError,
                              space.wrap("Invalid argument: negative time in sleep"))
     # as decreed by Guido, only the main thread can be
     # interrupted.
     main_thread = space.fromcache(State).main_thread
     interruptible = (main_thread == thread.get_ident())
     MAX = sys.maxint / 1000.0 # > 24 days
     while secs > MAX:
         _simple_sleep(space, MAX, interruptible)
         secs -= MAX
     _simple_sleep(space, secs, interruptible)
Пример #28
0
 def leave_thread(self, space):
     "Notification that the current thread is about to stop."
     from pypy.module.thread.os_local import thread_is_stopping
     ec = self.get_ec()
     if ec is not None:
         try:
             thread_is_stopping(ec)
         finally:
             self.raw_thread_local.set(None)
             ident = rthread.get_ident()
             try:
                 del self._valuedict[ident]
             except KeyError:
                 pass
Пример #29
0
 def __enter__(self):
     # This is a simple recursive lock implementation
     if self.space.config.objspace.usemodules.thread:
         from rpython.rlib import rthread
         #
         tid = rthread.get_ident()
         if tid != self.lock_owner:
             if self.lock is None:
                 self.lock = self.space.allocate_lock()
             self.lock.acquire(True)
             assert self.lock_owner == 0
             assert self.rec_level == 0
             self.lock_owner = tid
     self.rec_level += 1
Пример #30
0
 def run(space, w_callable, args):
     # add the ExecutionContext to space.threadlocals
     space.threadlocals.enter_thread(space)
     try:
         space.call_args(w_callable, args)
     except OperationError as e:
         if not e.match(space, space.w_SystemExit):
             ident = rthread.get_ident()
             where = "thread %d started by " % ident
             e.write_unraisable(space, where, w_callable, with_traceback=True)
         e.clear(space)
     # clean up space.threadlocals to remove the ExecutionContext
     # entry corresponding to the current thread
     space.threadlocals.leave_thread(space)
Пример #31
0
 def leave_thread(self, space):
     "Notification that the current thread is about to stop."
     from pypy.module.thread.os_local import thread_is_stopping
     ec = self.get_ec()
     if ec is not None:
         try:
             thread_is_stopping(ec)
         finally:
             self.raw_thread_local.set(None)
             ident = rthread.get_ident()
             try:
                 del self._valuedict[ident]
             except KeyError:
                 pass
Пример #32
0
 def setvalue(self, value):
     ident = rthread.get_ident()
     if value is not None:
         if self._mainthreadident == 0:
             value._signals_enabled = 1    # the main thread is enabled
             self._mainthreadident = ident
         self._valuedict[ident] = value
     else:
         try:
             del self._valuedict[ident]
         except KeyError:
             pass
     # update the minicache to prevent it from containing an outdated value
     self._mostrecentkey = ident
     self._mostrecentvalue = value
Пример #33
0
 def runme(main=False):
     j = 0
     for i in range(N + [-skew, skew][main]):
         state.datalen1 += 1  # try to crash if the GIL is not
         state.datalen2 += 1  # correctly acquired
         state.data.append((thread.get_ident(), i))
         state.datalen3 += 1
         state.datalen4 += 1
         assert state.datalen1 == len(state.data)
         assert state.datalen2 == len(state.data)
         assert state.datalen3 == len(state.data)
         assert state.datalen4 == len(state.data)
         debug_print(main, i, state.datalen4)
         rgil.yield_thread()
         assert i == j
         j += 1
Пример #34
0
 def runme(main=False):
     j = 0
     for i in range(N + [-skew, skew][main]):
         state.datalen1 += 1   # try to crash if the GIL is not
         state.datalen2 += 1   # correctly acquired
         state.data.append((thread.get_ident(), i))
         state.datalen3 += 1
         state.datalen4 += 1
         assert state.datalen1 == len(state.data)
         assert state.datalen2 == len(state.data)
         assert state.datalen3 == len(state.data)
         assert state.datalen4 == len(state.data)
         debug_print(main, i, state.datalen4)
         gil.do_yield_thread()
         assert i == j
         j += 1
Пример #35
0
    def acquire(self, space, block=True, w_timeout=None):
        # check whether we already own the lock
        if self.kind == RECURSIVE_MUTEX and self._ismine():
            self.count += 1
            return space.w_True

        try:
            got = semlock_acquire(self, space, block, w_timeout)
        except OSError as e:
            raise wrap_oserror(space, e)

        if got:
            self.last_tid = rthread.get_ident()
            self.count += 1
            return space.w_True
        else:
            return space.w_False
Пример #36
0
    def release_w(self, space):
        """Release the lock, allowing another thread that is blocked waiting for
        the lock to acquire the lock.  The lock must be in the locked state,
        and must be locked by the same thread that unlocks it; otherwise a
        `RuntimeError` is raised.

        Do note that if the lock was acquire()d several times in a row by the
        current thread, release() needs to be called as many times for the lock
        to be available for other threads."""
        tid = rthread.get_ident()
        if self.rlock_count == 0 or self.rlock_owner != tid:
            raise oefmt(space.w_RuntimeError,
                        "cannot release un-acquired lock")
        self.rlock_count -= 1
        if self.rlock_count == 0:
            self.rlock_owner = 0
            self.lock.release()
Пример #37
0
    def acquire(self, space, block=True, w_timeout=None):
        # check whether we already own the lock
        if self.kind == RECURSIVE_MUTEX and self._ismine():
            self.count += 1
            return space.w_True

        try:
            got = semlock_acquire(self, space, block, w_timeout)
        except OSError as e:
            raise wrap_oserror(space, e)

        if got:
            self.last_tid = rthread.get_ident()
            self.count += 1
            return space.w_True
        else:
            return space.w_False
Пример #38
0
 def run(space, w_callable, args):
     # add the ExecutionContext to space.threadlocals
     space.threadlocals.enter_thread(space)
     try:
         space.call_args(w_callable, args)
     except OperationError as e:
         if not e.match(space, space.w_SystemExit):
             ident = rthread.get_ident()
             where = 'thread %d started by ' % ident
             e.write_unraisable(space,
                                where,
                                w_callable,
                                with_traceback=True)
         e.clear(space)
     # clean up space.threadlocals to remove the ExecutionContext
     # entry corresponding to the current thread
     space.threadlocals.leave_thread(space)
Пример #39
0
    def semlock_acquire(self, space, block, w_timeout):
        if not block:
            deadline = lltype.nullptr(TIMESPECP.TO)
        elif space.is_none(w_timeout):
            deadline = lltype.nullptr(TIMESPECP.TO)
        else:
            timeout = space.float_w(w_timeout)
            sec = int(timeout)
            nsec = int(1e9 * (timeout - sec) + 0.5)

            now_sec, now_usec = gettimeofday()

            deadline = lltype.malloc(TIMESPECP.TO, 1, flavor='raw')
            rffi.setintfield(deadline[0], 'c_tv_sec', now_sec + sec)
            rffi.setintfield(deadline[0], 'c_tv_nsec', now_usec * 1000 + nsec)
            val = (rffi.getintfield(deadline[0], 'c_tv_sec') +
                   rffi.getintfield(deadline[0], 'c_tv_nsec') / 1000000000)
            rffi.setintfield(deadline[0], 'c_tv_sec', val)
            val = rffi.getintfield(deadline[0], 'c_tv_nsec') % 1000000000
            rffi.setintfield(deadline[0], 'c_tv_nsec', val)
        try:
            while True:
                try:
                    if not block:
                        sem_trywait(self.handle)
                    elif not deadline:
                        sem_wait(self.handle)
                    else:
                        sem_timedwait(self.handle, deadline)
                except OSError as e:
                    if e.errno == errno.EINTR:
                        # again
                        _check_signals(space)
                        continue
                    elif e.errno in (errno.EAGAIN, errno.ETIMEDOUT):
                        return False
                    raise
                _check_signals(space)
                self.last_tid = rthread.get_ident()
                self.count += 1
                return True
        finally:
            if deadline:
                lltype.free(deadline, flavor='raw')
Пример #40
0
    def release_w(self, space):
        """Release a lock, decrementing the recursion level.

        If after the decrement it is zero, reset the lock to unlocked (not owned
        by any thread), and if any other threads are blocked waiting for the
        lock to become unlocked, allow exactly one of them to proceed. If after
        the decrement the recursion level is still nonzero, the lock remains
        locked and owned by the calling thread.

        Only call this method when the calling thread owns the lock. A
        RuntimeError is raised if this method is called when the lock is
        unlocked.

        There is no return value.

        """
        if self.rlock_owner != rthread.get_ident():
            raise oefmt(space.w_RuntimeError,
                        "cannot release un-acquired lock")
        self.rlock_count -= 1
        if self.rlock_count == 0:
            self.rlock_owner = 0
            try_release(space, self.lock)
Пример #41
0
def sleep(space, w_secs):
    ns = timestamp_w(space, w_secs)
    if not (ns >= 0):
        raise oefmt(space.w_ValueError, "sleep length must be non-negative")
    end_time = _monotonic(space) + float(ns) / SECS_TO_NS
    while True:
        if _WIN:
            # as decreed by Guido, only the main thread can be
            # interrupted.
            main_thread = space.fromcache(State).main_thread
            interruptible = (main_thread == thread.get_ident())
            millisecs = ns // MS_TO_NS
            if millisecs == 0 or not interruptible:
                rtime.sleep(float(ns) / SECS_TO_NS)
                break
            interrupt_event = space.fromcache(State).get_interrupt_event()
            rwin32.ResetEvent(interrupt_event)
            rc = rwin32.WaitForSingleObject(interrupt_event, millisecs)
            if rc != rwin32.WAIT_OBJECT_0:
                break
        else:
            void = lltype.nullptr(rffi.VOIDP.TO)
            with lltype.scoped_alloc(TIMEVAL) as t:
                seconds = ns // SECS_TO_NS
                us = (ns % SECS_TO_NS) // US_TO_NS
                rffi.setintfield(t, 'c_tv_sec', int(seconds))
                rffi.setintfield(t, 'c_tv_usec', int(us))

                res = rffi.cast(rffi.LONG, c_select(0, void, void, void, t))
            if res == 0:
                break  # normal path
            if rposix.get_saved_errno() != EINTR:
                raise exception_from_saved_errno(space, space.w_OSError)
        space.getexecutioncontext().checksignals()
        secs = end_time - _monotonic(space)  # retry
        if secs <= 0:
            break
Пример #42
0
 def startup(self, space):
     self.main_thread = thread.get_ident()
     globalState.startup(space)
Пример #43
0
 def __enter__(self):
     if not self.lock.acquire(False):
         if self.owner == rthread.get_ident():
             raise self.operr
         self.lock.acquire(True)
     self.owner = rthread.get_ident()
Пример #44
0
 def __init__(self, ec):
     # this makes a loop between 'self' and 'ec'.  It should not prevent
     # the __del__ method here from being called.
     self.ec = ec
     ec._threadlocals_auto_free = self
     self.ident = rthread.get_ident()
Пример #45
0
 def try_enter_thread(self, space):
     if rthread.get_ident() in self._valuedict:
         return False
     self.enter_thread(space)
     return True
Пример #46
0
 def get_possibly_deleted_ec():
     ec1 = space.threadlocals.raw_thread_local.get()
     ec2 = space.threadlocals._valuedict.get(rthread.get_ident(), None)
     if ec1 is None and ec2 is not None:
         space.threadlocals.raw_thread_local.set(ec2)
     return space.threadlocals.__class__.get_ec(space.threadlocals)
Пример #47
0
 def _ismine(self):
     return self.count > 0 and rthread.get_ident() == self.last_tid
Пример #48
0
 def get_aid():
     """Return the thread identifier, cast to an (opaque) address."""
     return llmemory.cast_int_to_adr(rthread.get_ident())
Пример #49
0
 def startup(self, space):
     self.main_thread = thread.get_ident()
     globalState.startup(space)
Пример #50
0
 def get_ec(self):
     ec = self.raw_thread_local.get()
     if not we_are_translated():
         assert ec is self._valuedict.get(rthread.get_ident(), None)
     return ec
Пример #51
0
 def get_ec(self):
     ec = self.raw_thread_local.get()
     if not we_are_translated():
         assert ec is self._valuedict.get(rthread.get_ident(), None)
     return ec
Пример #52
0
 def _ismine(self):
     return self.count > 0 and rthread.get_ident() == self.last_tid
Пример #53
0
 def try_enter_thread(self, space):
     if rthread.get_ident() in self._valuedict:
         return False
     self.enter_thread(space)
     return True
Пример #54
0
 def _get_ident(self):
     from rpython.rlib import rthread
     tid = rthread.get_ident()
     assert tid != 0
     return tid
Пример #55
0
        return space.wrap(val)

    @unwrap_spec(block=bool)
    def acquire(self, space, block=True, w_timeout=None):
        # check whether we already own the lock
        if self.kind == RECURSIVE_MUTEX and self._ismine():
            self.count += 1
            return space.w_True

        try:
            got = semlock_acquire(self, space, block, w_timeout)
        except OSError, e:
            raise wrap_oserror(space, e)

        if got:
            self.last_tid = rthread.get_ident()
            self.count += 1
            return space.w_True
        else:
            return space.w_False

    def release(self, space):
        if self.kind == RECURSIVE_MUTEX:
            if not self._ismine():
                raise OperationError(
                    space.w_AssertionError,
                    space.wrap("attempt to release recursive lock"
                               " not owned by thread"))
            if self.count > 1:
                self.count -= 1
                return