Commit e97ed2aa authored by Jason Madden's avatar Jason Madden Committed by GitHub

Merge pull request #1131 from gevent/issue1127

Interpret -1 to select.poll.poll as blocking, especially under libuv
parents 9bc5da8b 3d97a54b
......@@ -131,6 +131,12 @@
not previously supported, is not possible now. See
:issue:`1226`.
- :meth:`gevent.select.poll.poll` now interprets a *timeout* of -1 the
same as a *timeout* of *None* as the standard requires. Previously,
on libuv this was interpreted the same as a *timeout* of 0. In
addition, all *timeout* values less than zero are interpreted like
*None* (as they always were under libev). See :issue:`1127`.
1.3a1 (2018-01-27)
==================
......
......@@ -114,7 +114,7 @@ class _AbstractLinkable(object):
# rely on the exact return values, not just truthish-ness
return False
finally:
timer.cancel()
timer.close()
finally:
self.unlink(switch)
......
......@@ -2,7 +2,7 @@
"""
Waiting for I/O completion.
"""
from __future__ import absolute_import
from __future__ import absolute_import, division, print_function
import sys
......@@ -230,6 +230,10 @@ if original_poll is not None:
.. versionchanged:: 1.2a1
File descriptors that are closed are reported with POLLNVAL.
.. versionchanged:: 1.3a2
Under libuv, interpret *timeout* values less than 0 the same as *None*,
i.e., block. This was always the case with libev.
"""
result = PollResult()
watchers = []
......@@ -241,8 +245,21 @@ if original_poll is not None:
watchers.append(watcher)
watcher.priority = MAXPRI
watcher.start(result.add_event, fd, pass_events=True)
if timeout is not None and timeout > -1:
timeout /= 1000.0
if timeout is not None:
if timeout < 0:
# The docs only say specifically that -1 itself
# is supposed to block forever. Many, but not all
# OS's accept any negative number to mean that. Some
# OS's raise errors for anything negative but not -1.
# Python 3.7 changes to always pass exactly -1 in that
# case from selectors.
# Our Timeout class currently does not have a defined behaviour
# for negative values. On libuv, it uses a check watcher and effectively
# doesn't block. On libev, it seems to block. In either case, we
# *want* to block, so turn this into the sure fire block request.
timeout = None
elif timeout:
timeout /= 1000.0
result.event.wait(timeout=timeout)
return list(result.events)
finally:
......
......@@ -270,18 +270,6 @@ if LIBUV:
# crashes with EPERM, which aborts the epoll loop, even
# though it was allowed in in the first place.
'test_asyncore.FileWrapperTest.test_dispatcher',
# XXX Debug this.
# Fails on line 342:
# self.assertEqual(1, len(s.select(-1)))
# AssertionError 1 != 0
# Is the negative time not letting the loop cycle or something?
# The -1 currently passes all the way through select.poll to
# gevent.event.Event.wait to gevent.timeout.Timeout to gevent.libuv.loop.timer
# to gevent.libuv.watchers.timer, where I think it is reset to 0.001.
# Alternately, this comes right after a call to s.select(0); perhaps libuv
# isn't reporting twice? We cache the watchers, maybe we need a new watcher?
'test_selectors.PollSelectorTestCase.test_timeout',
]
......
......@@ -14,6 +14,7 @@ from greentest import util
from greentest.util import log
from greentest.sysinfo import RUNNING_ON_CI
from greentest.sysinfo import PYPY
from greentest.sysinfo import RESOLVER_ARES
from greentest import six
......@@ -344,6 +345,10 @@ def main():
print(util.getname(cmd, env=options.get('env'), setenv=options.get('setenv')))
print('%s tests found.' % len(tests))
else:
if PYPY and RESOLVER_ARES:
# XXX: Add a way to force these.
print("Not running tests on pypy with c-ares; not a supported configuration")
return
run_many(tests, configured_failing_tests=FAILING_TESTS, failfast=options.failfast, quiet=options.quiet)
......
......@@ -276,7 +276,7 @@ class TestCase(greentest.TestCase):
try:
self.server.stop()
finally:
timeout.cancel()
timeout.close()
# XXX currently listening socket is kept open in gevent.wsgi
def connect(self):
......@@ -351,7 +351,7 @@ class CommonTests(TestCase):
read_http(fd, code=404, reason='Not Found', body='not found')
fd.close()
finally:
timeout.cancel()
timeout.close()
except AssertionError as ex:
if ex is not exception:
raise
......@@ -1562,6 +1562,7 @@ class TestInputRaw(greentest.BaseTestCase):
i = self.make_input("2\r\n1", chunked_input=True)
self.assertRaises(IOError, i.readline)
@greentest.skipOnLibuvOnCIOnPyPy("Crashes. See https://github.com/gevent/gevent/issues/1130")
def test_32bit_overflow(self):
# https://github.com/gevent/gevent/issues/289
# Should not raise an OverflowError on Python 2
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment