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')
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"))
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