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
 def semlock_getvalue(self, space):
     if rwin32.WaitForSingleObject(self.handle, 0) == rwin32.WAIT_TIMEOUT:
         return 0
     previous_ptr = lltype.malloc(rffi.LONGP.TO, 1, flavor='raw')
     try:
         if not _ReleaseSemaphore(self.handle, 1, previous_ptr):
             raise rwin32.lastSavedWindowsError("ReleaseSemaphore")
         return intmask(previous_ptr[0]) + 1
     finally:
         lltype.free(previous_ptr, flavor='raw')
Esempio n. 3
0
 def _simple_sleep(space, secs, interruptible):
     if secs == 0.0 or not interruptible:
         rtime.sleep(secs)
     else:
         millisecs = int(secs * 1000)
         interrupt_event = space.fromcache(State).get_interrupt_event()
         rwin32.ResetEvent(interrupt_event)
         rc = rwin32.WaitForSingleObject(interrupt_event, millisecs)
         if rc == rwin32.WAIT_OBJECT_0:
             # Yield to make sure real Python signal handler
             # called.
             rtime.sleep(0.001)
             raise wrap_oserror(space, OSError(EINTR,
                                               "sleep() interrupted"))
Esempio n. 4
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