Srikanth
Srikanth

Reputation: 1003

Why does `time.sleep()` raise an `IOError` beyond 100000000?

I'm using python 2.7.10 on a 64-bit Mac OS X machine. Why does time.sleep() raise an IOError beyond 100000000?

In the example below, time.sleep(100000000) works, but time.sleep(100000001) raises IOError

$ python
Python 2.7.10 (default, Oct  6 2017, 22:29:07) 
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import time
>>> time.sleep(100000000)
^CTraceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyboardInterrupt
>>>
>>>
>>> time.sleep(100000001)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 22] Invalid argument

Upvotes: 3

Views: 258

Answers (1)

user149341
user149341

Reputation:

This behavior is specific to macOS, not to Python. Python uses the select() function to implement sleep, and Perl exhibits the same behavior on macOS if you try to run select with a timeout of over 1e8 seconds:

# perl -E 'select $x, $x, $x, 100000001; say $!'
Invalid argument

The itimerfix function in the XNU kernel looks like a likely culprit for this behavior:

/*
 * Check that a proposed value to load into the .it_value or
 * .it_interval part of an interval timer is acceptable.
 */
int
itimerfix(
    struct timeval *tv)
{

    if (tv->tv_sec < 0 || tv->tv_sec > 100000000 ||
        tv->tv_usec < 0 || tv->tv_usec >= 1000000)
        return (EINVAL);
    return (0);
}

Upvotes: 4

Related Questions