-
-
Notifications
You must be signed in to change notification settings - Fork 30.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bpo-31786: Make select.poll.poll block if ms < 0 for every value of ms #4003
Conversation
Following @Haypo and @serhiy-storchaka discussion in the issue: Please, if you prefer a better/different way of dealing with this issue, I am more than happy to update the PR with the required changes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ms > 0 doesn't seem to be correct to me.
I prefer to fix the rouding and fix all functions.
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase |
This part doesn't look correct to me too. But the test may be useful if make it testing other infinity timeout values. They are not tested explicitly. |
@Haypo I have implemented @serhiy-storchaka I have updated the test so it takes into account more infinite timeout values. If you prefer a different implementation or use this in more/less places, say so and I will update this PR. Thank you for your time reviewing this PR! 😄 |
I have made the requested changes; please review again |
Thanks for making the requested changes! @Haypo: please review the changes made to this pull request. |
Python/pytime.c
Outdated
d = floor(d); | ||
} | ||
else { | ||
d = (d < 0.0) ? floor(d) : ceil(d); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add assert(round == _PyTime_ROUND_UP)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 5c58695
Lib/test/test_poll.py
Outdated
@unittest.skipUnless(threading, 'Threading required for this test.') | ||
@reap_threads | ||
def test_poll_blocks_with_negative_ms(self): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are too much empty lines. I think the code would look better without them. Empty lines should be used for separating functions, classes, and, sparingly, to indicate logical sections in functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 5c58695
Lib/test/test_poll.py
Outdated
|
||
for timeout_ms in [None, -1, -1.0, -0.1, -1e-100]: | ||
|
||
# GIVEN |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, but I don't understand what mean these GIVEN/WHEN/THEN.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I add then for clarity when testing (example).
I will delete them if you want.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 5c58695
Lib/test/test_poll.py
Outdated
# Create two file descriptors. This will be used to unlock | ||
# the blocking call to poll.poll inside the thread | ||
|
||
r, w = os.pipe() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A pair of descriptors is created for every timeout_ms
value, but they are closed only after finishing the test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 5c58695
… _PyTime_ROUND_CEILING
Modules/selectmodule.c
Outdated
@@ -594,7 +594,7 @@ poll_poll(pollObject *self, PyObject *args) | |||
poll_result = 0; | |||
break; | |||
} | |||
ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING); | |||
ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_UP); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since timeout
>= 0, there is no difference between _PyTime_ROUND_CEILING
and _PyTime_ROUND_UP
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 5c96cd6
Modules/selectmodule.c
Outdated
@@ -282,7 +282,7 @@ select_select(PyObject *self, PyObject *args) | |||
n = 0; | |||
break; | |||
} | |||
_PyTime_AsTimeval_noraise(timeout, &tv, _PyTime_ROUND_CEILING); | |||
_PyTime_AsTimeval_noraise(timeout, &tv, _PyTime_ROUND_UP); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since timeout
>= 0, there is no difference between _PyTime_ROUND_CEILING
and _PyTime_ROUND_UP
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 5c96cd6
Modules/selectmodule.c
Outdated
@@ -221,7 +221,7 @@ select_select(PyObject *self, PyObject *args) | |||
return NULL; | |||
} | |||
|
|||
if (_PyTime_AsTimeval(timeout, &tv, _PyTime_ROUND_CEILING) == -1) | |||
if (_PyTime_AsTimeval(timeout, &tv, _PyTime_ROUND_UP) == -1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
timeout
above is rounded with _PyTime_ROUND_CEILING
. Negative values between -1e-9 and 0 already are rounded to 0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 5c96cd6
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't _PyTime_ROUND_UP
be used instead in _PyTime_FromSecondsObject()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes! Corrected in 3f1f553. I am sorry if I miss a few places. A combination of ROUND_CEILING and ROUND_UP was causing a rounding error in test.eintrdata.eintr_tester.TimeEINTRTest and I was a bit paranoid and disoriented when changing these. 😞
Should I add a NEWS entry? |
Yes, this change requires a NEWS entry. |
Modules/selectmodule.c
Outdated
@@ -213,7 +213,7 @@ select_select(PyObject *self, PyObject *args) | |||
tvp = (struct timeval *)NULL; | |||
else { | |||
if (_PyTime_FromSecondsObject(&timeout, timeout_obj, | |||
_PyTime_ROUND_CEILING) < 0) { | |||
_PyTime_ROUND_UP) < 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Different direction of rounding shouldn't be mixed. Use _PyTime_ROUND_UP
in _PyTime_AsTimeval()
below, otherwise the timeout from -999 to -1 nanoseconds will be rounded to 0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Solved in 3f7ccda.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, this is not needed. At line 285 the value is not negative.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👌
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the patience!
Thanks @pablogsal for the PR, and @serhiy-storchaka for merging it 🌮🎉.. I'm working now to backport this PR to: 2.7, 3.6. |
Sorry, @pablogsal and @serhiy-storchaka, I could not cleanly backport this to |
Thanks @pablogsal for the PR, and @serhiy-storchaka for merging it 🌮🎉.. I'm working now to backport this PR to: 2.7, 3.6. |
Sorry, @pablogsal and @serhiy-storchaka, I could not cleanly backport this to |
2 similar comments
Sorry, @pablogsal and @serhiy-storchaka, I could not cleanly backport this to |
Sorry, @pablogsal and @serhiy-storchaka, I could not cleanly backport this to |
Sorry, @pablogsal and @serhiy-storchaka, I could not cleanly backport this to |
1 similar comment
Sorry, @pablogsal and @serhiy-storchaka, I could not cleanly backport this to |
@Mariatta, seems @miss-islington tries to create backports again and again. |
I removed the "needs backport" labels to prevent the issue. |
Do you mind to backport this to 3.6 and 2.7 @pablogsal? |
@serhiy-storchaka No problem! Should I do this before fixing the other functions? Thank you very much for your patience and time, @Haypo and @serhiy-storchaka ! 😄 |
Please do this before #3277 be merged. |
😕 Thanks for the ping! I'll take a look at miss-islington's logs to see what's going on. |
I opened a bug 🐛 python/miss-islington#35 |
…meout is a small negative value. (pythonGH-4003). (cherry picked from commit 2c15b29)
@Haypo, @serhiy-storchaka: I have backported this to 3.6: #4022 . I am wondering if this can be packported directly to 2.7... The reason is that |
If this is not relevant to 2.7, it is worth to backport just tests. |
Sorry, I did not explain correctly: |
…meout is a small negative value. (pythonGH-4003). (cherry picked from commit 2c15b29)
The test is backported by #4031. |
Acording to the documentation select.poll.poll() is blocked for infinite timeout if the timeout argument is negative but:
This is due to rounding issues when making the syscall. This PR fixes that so the call to
poll.poll
will block if the argument is negative.https://bugs.python.org/issue31786