You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Alright - you may very well consider this to be a stupid idea and everything, but I figured I'd report it anyway, just so it's there even if you decide to ignore it.
Now, as I replied there myself, you would in fact think that this can lead to infinite loops, but not really in a select/poll loop in the socket server, hence this report.
We have the following code:
[...]
iftimeoutisnotNone:
deadline=time() +timeout# Wait until a request arrives or the timeout expires - the loop is# necessary to accommodate early wakeups due to EINTR.with_ServerSelector() asselector:
selector.register(self, selectors.EVENT_READ)
whileTrue:
ready=selector.select(timeout)
ifready:
returnself._handle_request_noblock()
else:
iftimeoutisnotNone:
timeout=deadline-time()
iftimeout<0:
returnself.handle_timeout()
Assume that a timeout is given, so deadline is set to time() + timeout.
Now, if selector.select(timeout) returns [] because nothing was ready for reading, you'd expect us to treat this as a timeout, right?
However, in my case of virtual time with infinite processing power, it doesn't.
Let's say that timeout is 1 (second) and that the call to time() returned 10000 (clearly not realistic, but doesn't matter). Now, in a virtual time implementation with infinite processing power, select(timeout) will sleep for *exactly* 1 second, and return nothing is ready. Then, in the else: branch, we set "timeout = deadline - time()" - but now time will return 10001 (remember we slept for exactly 1 second), and timeout will be 0. We will thus not handle a timeout, instead, we'll go into select() again with a timeout of 0. Due to the "infinite processing power" aspect of this system, this will happen over and over again.
The trivial fix here is to handle it as a timeout "if timeout <= 0" rather than just "if timeout < 0".
Obviously, I can also fix my virtual time system, for example, I can give it less processing power by actually interrupting the process after some real time (which I implemented in https://patchwork.ozlabs.org/patch/1095814/).
An alternative is to make every "what time is it now" request actually take some virtual time, thus the time() calls cannot return the same value over and over again. This also fixes the issue I saw.
But it stands to reason that if it should happen that the new timeout is actually 0, we should really treat it as a timeout here in this code and make it <=0 rather than just <0.
Activity
jmberg commentedon May 23, 2019
Hi,
Alright - you may very well consider this to be a stupid idea and everything, but I figured I'd report it anyway, just so it's there even if you decide to ignore it.
For context, I'm running python in a ARCH=um Linux system that has completely virtual time, using basically this patch:
https://patchwork.ozlabs.org/patch/1095055/
Now, as I replied there myself, you would in fact think that this can lead to infinite loops, but not really in a select/poll loop in the socket server, hence this report.
We have the following code:
Assume that a timeout is given, so deadline is set to time() + timeout.
Now, if selector.select(timeout) returns [] because nothing was ready for reading, you'd expect us to treat this as a timeout, right?
However, in my case of virtual time with infinite processing power, it doesn't.
Let's say that timeout is 1 (second) and that the call to time() returned 10000 (clearly not realistic, but doesn't matter). Now, in a virtual time implementation with infinite processing power, select(timeout) will sleep for *exactly* 1 second, and return nothing is ready. Then, in the else: branch, we set "timeout = deadline - time()" - but now time will return 10001 (remember we slept for exactly 1 second), and timeout will be 0. We will thus not handle a timeout, instead, we'll go into select() again with a timeout of 0. Due to the "infinite processing power" aspect of this system, this will happen over and over again.
The trivial fix here is to handle it as a timeout "if timeout <= 0" rather than just "if timeout < 0".
Obviously, I can also fix my virtual time system, for example, I can give it less processing power by actually interrupting the process after some real time (which I implemented in https://patchwork.ozlabs.org/patch/1095814/).
An alternative is to make every "what time is it now" request actually take some virtual time, thus the time() calls cannot return the same value over and over again. This also fixes the issue I saw.
But it stands to reason that if it should happen that the new timeout is actually 0, we should really treat it as a timeout here in this code and make it <=0 rather than just <0.
iritkatriel commentedon Feb 18, 2023
I don't understand what the bug report is, or what you are suggesting should change in python.
iritkatriel commentedon Mar 1, 2023
Oh, I see - that code snippet is from the stdlib, it's not your code. I understand now.