bpo-41182 selector: use DefaultSelector based upon implementation (GH-21257)
On some platform such as VMware ESXi, DefaultSelector fails to detect selector due to default value. This fix adds a check and uses the correct selector depending upon select implementation and actual call. Fixes: [bpo-41182]() Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
This commit is contained in:
parent
b9f6ac9d46
commit
bcd47837a9
|
@ -57,6 +57,7 @@ if sys.version_info >= (3, 5):
|
||||||
SelectorKey.data.__doc__ = ('''Optional opaque data associated to this file object.
|
SelectorKey.data.__doc__ = ('''Optional opaque data associated to this file object.
|
||||||
For example, this could be used to store a per-client session ID.''')
|
For example, this could be used to store a per-client session ID.''')
|
||||||
|
|
||||||
|
|
||||||
class _SelectorMapping(Mapping):
|
class _SelectorMapping(Mapping):
|
||||||
"""Mapping of file objects to selector keys."""
|
"""Mapping of file objects to selector keys."""
|
||||||
|
|
||||||
|
@ -580,16 +581,39 @@ if hasattr(select, 'kqueue'):
|
||||||
super().close()
|
super().close()
|
||||||
|
|
||||||
|
|
||||||
|
def _can_use(method):
|
||||||
|
"""Check if we can use the selector depending upon the
|
||||||
|
operating system. """
|
||||||
|
# Implementation based upon https://github.com/sethmlarson/selectors2/blob/master/selectors2.py
|
||||||
|
selector = getattr(select, method, None)
|
||||||
|
if selector is None:
|
||||||
|
# select module does not implement method
|
||||||
|
return False
|
||||||
|
# check if the OS and Kernel actually support the method. Call may fail with
|
||||||
|
# OSError: [Errno 38] Function not implemented
|
||||||
|
try:
|
||||||
|
selector_obj = selector()
|
||||||
|
if method == 'poll':
|
||||||
|
# check that poll actually works
|
||||||
|
selector_obj.poll(0)
|
||||||
|
else:
|
||||||
|
# close epoll, kqueue, and devpoll fd
|
||||||
|
selector_obj.close()
|
||||||
|
return True
|
||||||
|
except OSError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
# Choose the best implementation, roughly:
|
# Choose the best implementation, roughly:
|
||||||
# epoll|kqueue|devpoll > poll > select.
|
# epoll|kqueue|devpoll > poll > select.
|
||||||
# select() also can't accept a FD > FD_SETSIZE (usually around 1024)
|
# select() also can't accept a FD > FD_SETSIZE (usually around 1024)
|
||||||
if 'KqueueSelector' in globals():
|
if _can_use('kqueue'):
|
||||||
DefaultSelector = KqueueSelector
|
DefaultSelector = KqueueSelector
|
||||||
elif 'EpollSelector' in globals():
|
elif _can_use('epoll'):
|
||||||
DefaultSelector = EpollSelector
|
DefaultSelector = EpollSelector
|
||||||
elif 'DevpollSelector' in globals():
|
elif _can_use('devpoll'):
|
||||||
DefaultSelector = DevpollSelector
|
DefaultSelector = DevpollSelector
|
||||||
elif 'PollSelector' in globals():
|
elif _can_use('poll'):
|
||||||
DefaultSelector = PollSelector
|
DefaultSelector = PollSelector
|
||||||
else:
|
else:
|
||||||
DefaultSelector = SelectSelector
|
DefaultSelector = SelectSelector
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
selector: use DefaultSelector based upon implementation
|
Loading…
Reference in New Issue