static double floattime(void) { _PyTime_timeval t; _PyTime_gettimeofday(&t); return (double)t.tv_sec + t.tv_usec*0.000001; }
/* Helper to acquire an interruptible lock with a timeout. If the lock acquire * is interrupted, signal handlers are run, and if they raise an exception, * PY_LOCK_INTR is returned. Otherwise, PY_LOCK_ACQUIRED or PY_LOCK_FAILURE * are returned, depending on whether the lock can be acquired withing the * timeout. */ static PyLockStatus acquire_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds) { PyLockStatus r; _PyTime_timeval curtime; _PyTime_timeval endtime; if (microseconds > 0) { _PyTime_gettimeofday(&endtime); endtime.tv_sec += microseconds / (1000 * 1000); endtime.tv_usec += microseconds % (1000 * 1000); } do { Py_BEGIN_ALLOW_THREADS r = PyThread_acquire_lock_timed(lock, microseconds, 1); Py_END_ALLOW_THREADS if (r == PY_LOCK_INTR) { /* Run signal handlers if we were interrupted. Propagate * exceptions from signal handlers, such as KeyboardInterrupt, by * passing up PY_LOCK_INTR. */ if (Py_MakePendingCalls() < 0) { return PY_LOCK_INTR; } /* If we're using a timeout, recompute the timeout after processing * signals, since those can take time. */ if (microseconds >= 0) { _PyTime_gettimeofday(&curtime); microseconds = ((endtime.tv_sec - curtime.tv_sec) * 1000000 + (endtime.tv_usec - curtime.tv_usec)); /* Check for negative values, since those mean block forever. */ if (microseconds <= 0) { r = PY_LOCK_FAILURE; } } } } while (r == PY_LOCK_INTR); /* Retry if we were interrupted. */ return r; }