Check if the OS can allocate the struct
@@ -539,6 +539,20 @@ if not hasattr(select, 'select'): # Platform-specific: AppEngine
HAS_SELECT = False
+def _can_allocate(struct):
+ """ Checks that select structs can be allocated
+ by the underlying operating system, not just
+ advertised by the select module. We don't check
+ select() because we'll be hopeful that most
+ platforms that don't have it available will not
+ advertise it. (ie: GAE) """
+ try:
+ getattr(select, struct)().close()
+ return True
+ except (OSError, AttributeError):
+ return False
+
+
# Choose the best implementation, roughly:
# kqueue == epoll > poll > select. Devpoll not supported. (See above)
# select() also can't accept a FD > FD_SETSIZE (usually around 1024)
@@ -547,11 +561,11 @@ def _default_selector(*_):
detect if the select module is being monkey-patched incorrectly
by eventlet, greenlet, and preserve proper behavior. """
global DefaultSelector
- if hasattr(select, 'kqueue'): # Platform-specific: Mac OS
+ if hasattr(select, 'kqueue') and _can_allocate('kqueue'): # Platform-specific: Mac OS
selector_type = KqueueSelector
- elif hasattr(select, 'epoll'): # Platform-specific: Linux
+ elif hasattr(select, 'epoll') and _can_allocate('epoll'): # Platform-specific: Linux
selector_type = EpollSelector
- elif hasattr(select, 'poll'): # Platform-specific: Linux
+ elif hasattr(select, 'poll') and _can_allocate('poll'): # Platform-specific: Linux
selector_type = PollSelector
elif hasattr(select, 'select'): # Platform-specific: Windows
selector_type = SelectSelector
