1*cda5da8dSAndroid Build Coastguard Worker"""Selectors module. 2*cda5da8dSAndroid Build Coastguard Worker 3*cda5da8dSAndroid Build Coastguard WorkerThis module allows high-level and efficient I/O multiplexing, built upon the 4*cda5da8dSAndroid Build Coastguard Worker`select` module primitives. 5*cda5da8dSAndroid Build Coastguard Worker""" 6*cda5da8dSAndroid Build Coastguard Worker 7*cda5da8dSAndroid Build Coastguard Worker 8*cda5da8dSAndroid Build Coastguard Workerfrom abc import ABCMeta, abstractmethod 9*cda5da8dSAndroid Build Coastguard Workerfrom collections import namedtuple 10*cda5da8dSAndroid Build Coastguard Workerfrom collections.abc import Mapping 11*cda5da8dSAndroid Build Coastguard Workerimport math 12*cda5da8dSAndroid Build Coastguard Workerimport select 13*cda5da8dSAndroid Build Coastguard Workerimport sys 14*cda5da8dSAndroid Build Coastguard Worker 15*cda5da8dSAndroid Build Coastguard Worker 16*cda5da8dSAndroid Build Coastguard Worker# generic events, that must be mapped to implementation-specific ones 17*cda5da8dSAndroid Build Coastguard WorkerEVENT_READ = (1 << 0) 18*cda5da8dSAndroid Build Coastguard WorkerEVENT_WRITE = (1 << 1) 19*cda5da8dSAndroid Build Coastguard Worker 20*cda5da8dSAndroid Build Coastguard Worker 21*cda5da8dSAndroid Build Coastguard Workerdef _fileobj_to_fd(fileobj): 22*cda5da8dSAndroid Build Coastguard Worker """Return a file descriptor from a file object. 23*cda5da8dSAndroid Build Coastguard Worker 24*cda5da8dSAndroid Build Coastguard Worker Parameters: 25*cda5da8dSAndroid Build Coastguard Worker fileobj -- file object or file descriptor 26*cda5da8dSAndroid Build Coastguard Worker 27*cda5da8dSAndroid Build Coastguard Worker Returns: 28*cda5da8dSAndroid Build Coastguard Worker corresponding file descriptor 29*cda5da8dSAndroid Build Coastguard Worker 30*cda5da8dSAndroid Build Coastguard Worker Raises: 31*cda5da8dSAndroid Build Coastguard Worker ValueError if the object is invalid 32*cda5da8dSAndroid Build Coastguard Worker """ 33*cda5da8dSAndroid Build Coastguard Worker if isinstance(fileobj, int): 34*cda5da8dSAndroid Build Coastguard Worker fd = fileobj 35*cda5da8dSAndroid Build Coastguard Worker else: 36*cda5da8dSAndroid Build Coastguard Worker try: 37*cda5da8dSAndroid Build Coastguard Worker fd = int(fileobj.fileno()) 38*cda5da8dSAndroid Build Coastguard Worker except (AttributeError, TypeError, ValueError): 39*cda5da8dSAndroid Build Coastguard Worker raise ValueError("Invalid file object: " 40*cda5da8dSAndroid Build Coastguard Worker "{!r}".format(fileobj)) from None 41*cda5da8dSAndroid Build Coastguard Worker if fd < 0: 42*cda5da8dSAndroid Build Coastguard Worker raise ValueError("Invalid file descriptor: {}".format(fd)) 43*cda5da8dSAndroid Build Coastguard Worker return fd 44*cda5da8dSAndroid Build Coastguard Worker 45*cda5da8dSAndroid Build Coastguard Worker 46*cda5da8dSAndroid Build Coastguard WorkerSelectorKey = namedtuple('SelectorKey', ['fileobj', 'fd', 'events', 'data']) 47*cda5da8dSAndroid Build Coastguard Worker 48*cda5da8dSAndroid Build Coastguard WorkerSelectorKey.__doc__ = """SelectorKey(fileobj, fd, events, data) 49*cda5da8dSAndroid Build Coastguard Worker 50*cda5da8dSAndroid Build Coastguard Worker Object used to associate a file object to its backing 51*cda5da8dSAndroid Build Coastguard Worker file descriptor, selected event mask, and attached data. 52*cda5da8dSAndroid Build Coastguard Worker""" 53*cda5da8dSAndroid Build Coastguard WorkerSelectorKey.fileobj.__doc__ = 'File object registered.' 54*cda5da8dSAndroid Build Coastguard WorkerSelectorKey.fd.__doc__ = 'Underlying file descriptor.' 55*cda5da8dSAndroid Build Coastguard WorkerSelectorKey.events.__doc__ = 'Events that must be waited for on this file object.' 56*cda5da8dSAndroid Build Coastguard WorkerSelectorKey.data.__doc__ = ('''Optional opaque data associated to this file object. 57*cda5da8dSAndroid Build Coastguard WorkerFor example, this could be used to store a per-client session ID.''') 58*cda5da8dSAndroid Build Coastguard Worker 59*cda5da8dSAndroid Build Coastguard Worker 60*cda5da8dSAndroid Build Coastguard Workerclass _SelectorMapping(Mapping): 61*cda5da8dSAndroid Build Coastguard Worker """Mapping of file objects to selector keys.""" 62*cda5da8dSAndroid Build Coastguard Worker 63*cda5da8dSAndroid Build Coastguard Worker def __init__(self, selector): 64*cda5da8dSAndroid Build Coastguard Worker self._selector = selector 65*cda5da8dSAndroid Build Coastguard Worker 66*cda5da8dSAndroid Build Coastguard Worker def __len__(self): 67*cda5da8dSAndroid Build Coastguard Worker return len(self._selector._fd_to_key) 68*cda5da8dSAndroid Build Coastguard Worker 69*cda5da8dSAndroid Build Coastguard Worker def __getitem__(self, fileobj): 70*cda5da8dSAndroid Build Coastguard Worker try: 71*cda5da8dSAndroid Build Coastguard Worker fd = self._selector._fileobj_lookup(fileobj) 72*cda5da8dSAndroid Build Coastguard Worker return self._selector._fd_to_key[fd] 73*cda5da8dSAndroid Build Coastguard Worker except KeyError: 74*cda5da8dSAndroid Build Coastguard Worker raise KeyError("{!r} is not registered".format(fileobj)) from None 75*cda5da8dSAndroid Build Coastguard Worker 76*cda5da8dSAndroid Build Coastguard Worker def __iter__(self): 77*cda5da8dSAndroid Build Coastguard Worker return iter(self._selector._fd_to_key) 78*cda5da8dSAndroid Build Coastguard Worker 79*cda5da8dSAndroid Build Coastguard Worker 80*cda5da8dSAndroid Build Coastguard Workerclass BaseSelector(metaclass=ABCMeta): 81*cda5da8dSAndroid Build Coastguard Worker """Selector abstract base class. 82*cda5da8dSAndroid Build Coastguard Worker 83*cda5da8dSAndroid Build Coastguard Worker A selector supports registering file objects to be monitored for specific 84*cda5da8dSAndroid Build Coastguard Worker I/O events. 85*cda5da8dSAndroid Build Coastguard Worker 86*cda5da8dSAndroid Build Coastguard Worker A file object is a file descriptor or any object with a `fileno()` method. 87*cda5da8dSAndroid Build Coastguard Worker An arbitrary object can be attached to the file object, which can be used 88*cda5da8dSAndroid Build Coastguard Worker for example to store context information, a callback, etc. 89*cda5da8dSAndroid Build Coastguard Worker 90*cda5da8dSAndroid Build Coastguard Worker A selector can use various implementations (select(), poll(), epoll()...) 91*cda5da8dSAndroid Build Coastguard Worker depending on the platform. The default `Selector` class uses the most 92*cda5da8dSAndroid Build Coastguard Worker efficient implementation on the current platform. 93*cda5da8dSAndroid Build Coastguard Worker """ 94*cda5da8dSAndroid Build Coastguard Worker 95*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 96*cda5da8dSAndroid Build Coastguard Worker def register(self, fileobj, events, data=None): 97*cda5da8dSAndroid Build Coastguard Worker """Register a file object. 98*cda5da8dSAndroid Build Coastguard Worker 99*cda5da8dSAndroid Build Coastguard Worker Parameters: 100*cda5da8dSAndroid Build Coastguard Worker fileobj -- file object or file descriptor 101*cda5da8dSAndroid Build Coastguard Worker events -- events to monitor (bitwise mask of EVENT_READ|EVENT_WRITE) 102*cda5da8dSAndroid Build Coastguard Worker data -- attached data 103*cda5da8dSAndroid Build Coastguard Worker 104*cda5da8dSAndroid Build Coastguard Worker Returns: 105*cda5da8dSAndroid Build Coastguard Worker SelectorKey instance 106*cda5da8dSAndroid Build Coastguard Worker 107*cda5da8dSAndroid Build Coastguard Worker Raises: 108*cda5da8dSAndroid Build Coastguard Worker ValueError if events is invalid 109*cda5da8dSAndroid Build Coastguard Worker KeyError if fileobj is already registered 110*cda5da8dSAndroid Build Coastguard Worker OSError if fileobj is closed or otherwise is unacceptable to 111*cda5da8dSAndroid Build Coastguard Worker the underlying system call (if a system call is made) 112*cda5da8dSAndroid Build Coastguard Worker 113*cda5da8dSAndroid Build Coastguard Worker Note: 114*cda5da8dSAndroid Build Coastguard Worker OSError may or may not be raised 115*cda5da8dSAndroid Build Coastguard Worker """ 116*cda5da8dSAndroid Build Coastguard Worker raise NotImplementedError 117*cda5da8dSAndroid Build Coastguard Worker 118*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 119*cda5da8dSAndroid Build Coastguard Worker def unregister(self, fileobj): 120*cda5da8dSAndroid Build Coastguard Worker """Unregister a file object. 121*cda5da8dSAndroid Build Coastguard Worker 122*cda5da8dSAndroid Build Coastguard Worker Parameters: 123*cda5da8dSAndroid Build Coastguard Worker fileobj -- file object or file descriptor 124*cda5da8dSAndroid Build Coastguard Worker 125*cda5da8dSAndroid Build Coastguard Worker Returns: 126*cda5da8dSAndroid Build Coastguard Worker SelectorKey instance 127*cda5da8dSAndroid Build Coastguard Worker 128*cda5da8dSAndroid Build Coastguard Worker Raises: 129*cda5da8dSAndroid Build Coastguard Worker KeyError if fileobj is not registered 130*cda5da8dSAndroid Build Coastguard Worker 131*cda5da8dSAndroid Build Coastguard Worker Note: 132*cda5da8dSAndroid Build Coastguard Worker If fileobj is registered but has since been closed this does 133*cda5da8dSAndroid Build Coastguard Worker *not* raise OSError (even if the wrapped syscall does) 134*cda5da8dSAndroid Build Coastguard Worker """ 135*cda5da8dSAndroid Build Coastguard Worker raise NotImplementedError 136*cda5da8dSAndroid Build Coastguard Worker 137*cda5da8dSAndroid Build Coastguard Worker def modify(self, fileobj, events, data=None): 138*cda5da8dSAndroid Build Coastguard Worker """Change a registered file object monitored events or attached data. 139*cda5da8dSAndroid Build Coastguard Worker 140*cda5da8dSAndroid Build Coastguard Worker Parameters: 141*cda5da8dSAndroid Build Coastguard Worker fileobj -- file object or file descriptor 142*cda5da8dSAndroid Build Coastguard Worker events -- events to monitor (bitwise mask of EVENT_READ|EVENT_WRITE) 143*cda5da8dSAndroid Build Coastguard Worker data -- attached data 144*cda5da8dSAndroid Build Coastguard Worker 145*cda5da8dSAndroid Build Coastguard Worker Returns: 146*cda5da8dSAndroid Build Coastguard Worker SelectorKey instance 147*cda5da8dSAndroid Build Coastguard Worker 148*cda5da8dSAndroid Build Coastguard Worker Raises: 149*cda5da8dSAndroid Build Coastguard Worker Anything that unregister() or register() raises 150*cda5da8dSAndroid Build Coastguard Worker """ 151*cda5da8dSAndroid Build Coastguard Worker self.unregister(fileobj) 152*cda5da8dSAndroid Build Coastguard Worker return self.register(fileobj, events, data) 153*cda5da8dSAndroid Build Coastguard Worker 154*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 155*cda5da8dSAndroid Build Coastguard Worker def select(self, timeout=None): 156*cda5da8dSAndroid Build Coastguard Worker """Perform the actual selection, until some monitored file objects are 157*cda5da8dSAndroid Build Coastguard Worker ready or a timeout expires. 158*cda5da8dSAndroid Build Coastguard Worker 159*cda5da8dSAndroid Build Coastguard Worker Parameters: 160*cda5da8dSAndroid Build Coastguard Worker timeout -- if timeout > 0, this specifies the maximum wait time, in 161*cda5da8dSAndroid Build Coastguard Worker seconds 162*cda5da8dSAndroid Build Coastguard Worker if timeout <= 0, the select() call won't block, and will 163*cda5da8dSAndroid Build Coastguard Worker report the currently ready file objects 164*cda5da8dSAndroid Build Coastguard Worker if timeout is None, select() will block until a monitored 165*cda5da8dSAndroid Build Coastguard Worker file object becomes ready 166*cda5da8dSAndroid Build Coastguard Worker 167*cda5da8dSAndroid Build Coastguard Worker Returns: 168*cda5da8dSAndroid Build Coastguard Worker list of (key, events) for ready file objects 169*cda5da8dSAndroid Build Coastguard Worker `events` is a bitwise mask of EVENT_READ|EVENT_WRITE 170*cda5da8dSAndroid Build Coastguard Worker """ 171*cda5da8dSAndroid Build Coastguard Worker raise NotImplementedError 172*cda5da8dSAndroid Build Coastguard Worker 173*cda5da8dSAndroid Build Coastguard Worker def close(self): 174*cda5da8dSAndroid Build Coastguard Worker """Close the selector. 175*cda5da8dSAndroid Build Coastguard Worker 176*cda5da8dSAndroid Build Coastguard Worker This must be called to make sure that any underlying resource is freed. 177*cda5da8dSAndroid Build Coastguard Worker """ 178*cda5da8dSAndroid Build Coastguard Worker pass 179*cda5da8dSAndroid Build Coastguard Worker 180*cda5da8dSAndroid Build Coastguard Worker def get_key(self, fileobj): 181*cda5da8dSAndroid Build Coastguard Worker """Return the key associated to a registered file object. 182*cda5da8dSAndroid Build Coastguard Worker 183*cda5da8dSAndroid Build Coastguard Worker Returns: 184*cda5da8dSAndroid Build Coastguard Worker SelectorKey for this file object 185*cda5da8dSAndroid Build Coastguard Worker """ 186*cda5da8dSAndroid Build Coastguard Worker mapping = self.get_map() 187*cda5da8dSAndroid Build Coastguard Worker if mapping is None: 188*cda5da8dSAndroid Build Coastguard Worker raise RuntimeError('Selector is closed') 189*cda5da8dSAndroid Build Coastguard Worker try: 190*cda5da8dSAndroid Build Coastguard Worker return mapping[fileobj] 191*cda5da8dSAndroid Build Coastguard Worker except KeyError: 192*cda5da8dSAndroid Build Coastguard Worker raise KeyError("{!r} is not registered".format(fileobj)) from None 193*cda5da8dSAndroid Build Coastguard Worker 194*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 195*cda5da8dSAndroid Build Coastguard Worker def get_map(self): 196*cda5da8dSAndroid Build Coastguard Worker """Return a mapping of file objects to selector keys.""" 197*cda5da8dSAndroid Build Coastguard Worker raise NotImplementedError 198*cda5da8dSAndroid Build Coastguard Worker 199*cda5da8dSAndroid Build Coastguard Worker def __enter__(self): 200*cda5da8dSAndroid Build Coastguard Worker return self 201*cda5da8dSAndroid Build Coastguard Worker 202*cda5da8dSAndroid Build Coastguard Worker def __exit__(self, *args): 203*cda5da8dSAndroid Build Coastguard Worker self.close() 204*cda5da8dSAndroid Build Coastguard Worker 205*cda5da8dSAndroid Build Coastguard Worker 206*cda5da8dSAndroid Build Coastguard Workerclass _BaseSelectorImpl(BaseSelector): 207*cda5da8dSAndroid Build Coastguard Worker """Base selector implementation.""" 208*cda5da8dSAndroid Build Coastguard Worker 209*cda5da8dSAndroid Build Coastguard Worker def __init__(self): 210*cda5da8dSAndroid Build Coastguard Worker # this maps file descriptors to keys 211*cda5da8dSAndroid Build Coastguard Worker self._fd_to_key = {} 212*cda5da8dSAndroid Build Coastguard Worker # read-only mapping returned by get_map() 213*cda5da8dSAndroid Build Coastguard Worker self._map = _SelectorMapping(self) 214*cda5da8dSAndroid Build Coastguard Worker 215*cda5da8dSAndroid Build Coastguard Worker def _fileobj_lookup(self, fileobj): 216*cda5da8dSAndroid Build Coastguard Worker """Return a file descriptor from a file object. 217*cda5da8dSAndroid Build Coastguard Worker 218*cda5da8dSAndroid Build Coastguard Worker This wraps _fileobj_to_fd() to do an exhaustive search in case 219*cda5da8dSAndroid Build Coastguard Worker the object is invalid but we still have it in our map. This 220*cda5da8dSAndroid Build Coastguard Worker is used by unregister() so we can unregister an object that 221*cda5da8dSAndroid Build Coastguard Worker was previously registered even if it is closed. It is also 222*cda5da8dSAndroid Build Coastguard Worker used by _SelectorMapping. 223*cda5da8dSAndroid Build Coastguard Worker """ 224*cda5da8dSAndroid Build Coastguard Worker try: 225*cda5da8dSAndroid Build Coastguard Worker return _fileobj_to_fd(fileobj) 226*cda5da8dSAndroid Build Coastguard Worker except ValueError: 227*cda5da8dSAndroid Build Coastguard Worker # Do an exhaustive search. 228*cda5da8dSAndroid Build Coastguard Worker for key in self._fd_to_key.values(): 229*cda5da8dSAndroid Build Coastguard Worker if key.fileobj is fileobj: 230*cda5da8dSAndroid Build Coastguard Worker return key.fd 231*cda5da8dSAndroid Build Coastguard Worker # Raise ValueError after all. 232*cda5da8dSAndroid Build Coastguard Worker raise 233*cda5da8dSAndroid Build Coastguard Worker 234*cda5da8dSAndroid Build Coastguard Worker def register(self, fileobj, events, data=None): 235*cda5da8dSAndroid Build Coastguard Worker if (not events) or (events & ~(EVENT_READ | EVENT_WRITE)): 236*cda5da8dSAndroid Build Coastguard Worker raise ValueError("Invalid events: {!r}".format(events)) 237*cda5da8dSAndroid Build Coastguard Worker 238*cda5da8dSAndroid Build Coastguard Worker key = SelectorKey(fileobj, self._fileobj_lookup(fileobj), events, data) 239*cda5da8dSAndroid Build Coastguard Worker 240*cda5da8dSAndroid Build Coastguard Worker if key.fd in self._fd_to_key: 241*cda5da8dSAndroid Build Coastguard Worker raise KeyError("{!r} (FD {}) is already registered" 242*cda5da8dSAndroid Build Coastguard Worker .format(fileobj, key.fd)) 243*cda5da8dSAndroid Build Coastguard Worker 244*cda5da8dSAndroid Build Coastguard Worker self._fd_to_key[key.fd] = key 245*cda5da8dSAndroid Build Coastguard Worker return key 246*cda5da8dSAndroid Build Coastguard Worker 247*cda5da8dSAndroid Build Coastguard Worker def unregister(self, fileobj): 248*cda5da8dSAndroid Build Coastguard Worker try: 249*cda5da8dSAndroid Build Coastguard Worker key = self._fd_to_key.pop(self._fileobj_lookup(fileobj)) 250*cda5da8dSAndroid Build Coastguard Worker except KeyError: 251*cda5da8dSAndroid Build Coastguard Worker raise KeyError("{!r} is not registered".format(fileobj)) from None 252*cda5da8dSAndroid Build Coastguard Worker return key 253*cda5da8dSAndroid Build Coastguard Worker 254*cda5da8dSAndroid Build Coastguard Worker def modify(self, fileobj, events, data=None): 255*cda5da8dSAndroid Build Coastguard Worker try: 256*cda5da8dSAndroid Build Coastguard Worker key = self._fd_to_key[self._fileobj_lookup(fileobj)] 257*cda5da8dSAndroid Build Coastguard Worker except KeyError: 258*cda5da8dSAndroid Build Coastguard Worker raise KeyError("{!r} is not registered".format(fileobj)) from None 259*cda5da8dSAndroid Build Coastguard Worker if events != key.events: 260*cda5da8dSAndroid Build Coastguard Worker self.unregister(fileobj) 261*cda5da8dSAndroid Build Coastguard Worker key = self.register(fileobj, events, data) 262*cda5da8dSAndroid Build Coastguard Worker elif data != key.data: 263*cda5da8dSAndroid Build Coastguard Worker # Use a shortcut to update the data. 264*cda5da8dSAndroid Build Coastguard Worker key = key._replace(data=data) 265*cda5da8dSAndroid Build Coastguard Worker self._fd_to_key[key.fd] = key 266*cda5da8dSAndroid Build Coastguard Worker return key 267*cda5da8dSAndroid Build Coastguard Worker 268*cda5da8dSAndroid Build Coastguard Worker def close(self): 269*cda5da8dSAndroid Build Coastguard Worker self._fd_to_key.clear() 270*cda5da8dSAndroid Build Coastguard Worker self._map = None 271*cda5da8dSAndroid Build Coastguard Worker 272*cda5da8dSAndroid Build Coastguard Worker def get_map(self): 273*cda5da8dSAndroid Build Coastguard Worker return self._map 274*cda5da8dSAndroid Build Coastguard Worker 275*cda5da8dSAndroid Build Coastguard Worker def _key_from_fd(self, fd): 276*cda5da8dSAndroid Build Coastguard Worker """Return the key associated to a given file descriptor. 277*cda5da8dSAndroid Build Coastguard Worker 278*cda5da8dSAndroid Build Coastguard Worker Parameters: 279*cda5da8dSAndroid Build Coastguard Worker fd -- file descriptor 280*cda5da8dSAndroid Build Coastguard Worker 281*cda5da8dSAndroid Build Coastguard Worker Returns: 282*cda5da8dSAndroid Build Coastguard Worker corresponding key, or None if not found 283*cda5da8dSAndroid Build Coastguard Worker """ 284*cda5da8dSAndroid Build Coastguard Worker try: 285*cda5da8dSAndroid Build Coastguard Worker return self._fd_to_key[fd] 286*cda5da8dSAndroid Build Coastguard Worker except KeyError: 287*cda5da8dSAndroid Build Coastguard Worker return None 288*cda5da8dSAndroid Build Coastguard Worker 289*cda5da8dSAndroid Build Coastguard Worker 290*cda5da8dSAndroid Build Coastguard Workerclass SelectSelector(_BaseSelectorImpl): 291*cda5da8dSAndroid Build Coastguard Worker """Select-based selector.""" 292*cda5da8dSAndroid Build Coastguard Worker 293*cda5da8dSAndroid Build Coastguard Worker def __init__(self): 294*cda5da8dSAndroid Build Coastguard Worker super().__init__() 295*cda5da8dSAndroid Build Coastguard Worker self._readers = set() 296*cda5da8dSAndroid Build Coastguard Worker self._writers = set() 297*cda5da8dSAndroid Build Coastguard Worker 298*cda5da8dSAndroid Build Coastguard Worker def register(self, fileobj, events, data=None): 299*cda5da8dSAndroid Build Coastguard Worker key = super().register(fileobj, events, data) 300*cda5da8dSAndroid Build Coastguard Worker if events & EVENT_READ: 301*cda5da8dSAndroid Build Coastguard Worker self._readers.add(key.fd) 302*cda5da8dSAndroid Build Coastguard Worker if events & EVENT_WRITE: 303*cda5da8dSAndroid Build Coastguard Worker self._writers.add(key.fd) 304*cda5da8dSAndroid Build Coastguard Worker return key 305*cda5da8dSAndroid Build Coastguard Worker 306*cda5da8dSAndroid Build Coastguard Worker def unregister(self, fileobj): 307*cda5da8dSAndroid Build Coastguard Worker key = super().unregister(fileobj) 308*cda5da8dSAndroid Build Coastguard Worker self._readers.discard(key.fd) 309*cda5da8dSAndroid Build Coastguard Worker self._writers.discard(key.fd) 310*cda5da8dSAndroid Build Coastguard Worker return key 311*cda5da8dSAndroid Build Coastguard Worker 312*cda5da8dSAndroid Build Coastguard Worker if sys.platform == 'win32': 313*cda5da8dSAndroid Build Coastguard Worker def _select(self, r, w, _, timeout=None): 314*cda5da8dSAndroid Build Coastguard Worker r, w, x = select.select(r, w, w, timeout) 315*cda5da8dSAndroid Build Coastguard Worker return r, w + x, [] 316*cda5da8dSAndroid Build Coastguard Worker else: 317*cda5da8dSAndroid Build Coastguard Worker _select = select.select 318*cda5da8dSAndroid Build Coastguard Worker 319*cda5da8dSAndroid Build Coastguard Worker def select(self, timeout=None): 320*cda5da8dSAndroid Build Coastguard Worker timeout = None if timeout is None else max(timeout, 0) 321*cda5da8dSAndroid Build Coastguard Worker ready = [] 322*cda5da8dSAndroid Build Coastguard Worker try: 323*cda5da8dSAndroid Build Coastguard Worker r, w, _ = self._select(self._readers, self._writers, [], timeout) 324*cda5da8dSAndroid Build Coastguard Worker except InterruptedError: 325*cda5da8dSAndroid Build Coastguard Worker return ready 326*cda5da8dSAndroid Build Coastguard Worker r = set(r) 327*cda5da8dSAndroid Build Coastguard Worker w = set(w) 328*cda5da8dSAndroid Build Coastguard Worker for fd in r | w: 329*cda5da8dSAndroid Build Coastguard Worker events = 0 330*cda5da8dSAndroid Build Coastguard Worker if fd in r: 331*cda5da8dSAndroid Build Coastguard Worker events |= EVENT_READ 332*cda5da8dSAndroid Build Coastguard Worker if fd in w: 333*cda5da8dSAndroid Build Coastguard Worker events |= EVENT_WRITE 334*cda5da8dSAndroid Build Coastguard Worker 335*cda5da8dSAndroid Build Coastguard Worker key = self._key_from_fd(fd) 336*cda5da8dSAndroid Build Coastguard Worker if key: 337*cda5da8dSAndroid Build Coastguard Worker ready.append((key, events & key.events)) 338*cda5da8dSAndroid Build Coastguard Worker return ready 339*cda5da8dSAndroid Build Coastguard Worker 340*cda5da8dSAndroid Build Coastguard Worker 341*cda5da8dSAndroid Build Coastguard Workerclass _PollLikeSelector(_BaseSelectorImpl): 342*cda5da8dSAndroid Build Coastguard Worker """Base class shared between poll, epoll and devpoll selectors.""" 343*cda5da8dSAndroid Build Coastguard Worker _selector_cls = None 344*cda5da8dSAndroid Build Coastguard Worker _EVENT_READ = None 345*cda5da8dSAndroid Build Coastguard Worker _EVENT_WRITE = None 346*cda5da8dSAndroid Build Coastguard Worker 347*cda5da8dSAndroid Build Coastguard Worker def __init__(self): 348*cda5da8dSAndroid Build Coastguard Worker super().__init__() 349*cda5da8dSAndroid Build Coastguard Worker self._selector = self._selector_cls() 350*cda5da8dSAndroid Build Coastguard Worker 351*cda5da8dSAndroid Build Coastguard Worker def register(self, fileobj, events, data=None): 352*cda5da8dSAndroid Build Coastguard Worker key = super().register(fileobj, events, data) 353*cda5da8dSAndroid Build Coastguard Worker poller_events = 0 354*cda5da8dSAndroid Build Coastguard Worker if events & EVENT_READ: 355*cda5da8dSAndroid Build Coastguard Worker poller_events |= self._EVENT_READ 356*cda5da8dSAndroid Build Coastguard Worker if events & EVENT_WRITE: 357*cda5da8dSAndroid Build Coastguard Worker poller_events |= self._EVENT_WRITE 358*cda5da8dSAndroid Build Coastguard Worker try: 359*cda5da8dSAndroid Build Coastguard Worker self._selector.register(key.fd, poller_events) 360*cda5da8dSAndroid Build Coastguard Worker except: 361*cda5da8dSAndroid Build Coastguard Worker super().unregister(fileobj) 362*cda5da8dSAndroid Build Coastguard Worker raise 363*cda5da8dSAndroid Build Coastguard Worker return key 364*cda5da8dSAndroid Build Coastguard Worker 365*cda5da8dSAndroid Build Coastguard Worker def unregister(self, fileobj): 366*cda5da8dSAndroid Build Coastguard Worker key = super().unregister(fileobj) 367*cda5da8dSAndroid Build Coastguard Worker try: 368*cda5da8dSAndroid Build Coastguard Worker self._selector.unregister(key.fd) 369*cda5da8dSAndroid Build Coastguard Worker except OSError: 370*cda5da8dSAndroid Build Coastguard Worker # This can happen if the FD was closed since it 371*cda5da8dSAndroid Build Coastguard Worker # was registered. 372*cda5da8dSAndroid Build Coastguard Worker pass 373*cda5da8dSAndroid Build Coastguard Worker return key 374*cda5da8dSAndroid Build Coastguard Worker 375*cda5da8dSAndroid Build Coastguard Worker def modify(self, fileobj, events, data=None): 376*cda5da8dSAndroid Build Coastguard Worker try: 377*cda5da8dSAndroid Build Coastguard Worker key = self._fd_to_key[self._fileobj_lookup(fileobj)] 378*cda5da8dSAndroid Build Coastguard Worker except KeyError: 379*cda5da8dSAndroid Build Coastguard Worker raise KeyError(f"{fileobj!r} is not registered") from None 380*cda5da8dSAndroid Build Coastguard Worker 381*cda5da8dSAndroid Build Coastguard Worker changed = False 382*cda5da8dSAndroid Build Coastguard Worker if events != key.events: 383*cda5da8dSAndroid Build Coastguard Worker selector_events = 0 384*cda5da8dSAndroid Build Coastguard Worker if events & EVENT_READ: 385*cda5da8dSAndroid Build Coastguard Worker selector_events |= self._EVENT_READ 386*cda5da8dSAndroid Build Coastguard Worker if events & EVENT_WRITE: 387*cda5da8dSAndroid Build Coastguard Worker selector_events |= self._EVENT_WRITE 388*cda5da8dSAndroid Build Coastguard Worker try: 389*cda5da8dSAndroid Build Coastguard Worker self._selector.modify(key.fd, selector_events) 390*cda5da8dSAndroid Build Coastguard Worker except: 391*cda5da8dSAndroid Build Coastguard Worker super().unregister(fileobj) 392*cda5da8dSAndroid Build Coastguard Worker raise 393*cda5da8dSAndroid Build Coastguard Worker changed = True 394*cda5da8dSAndroid Build Coastguard Worker if data != key.data: 395*cda5da8dSAndroid Build Coastguard Worker changed = True 396*cda5da8dSAndroid Build Coastguard Worker 397*cda5da8dSAndroid Build Coastguard Worker if changed: 398*cda5da8dSAndroid Build Coastguard Worker key = key._replace(events=events, data=data) 399*cda5da8dSAndroid Build Coastguard Worker self._fd_to_key[key.fd] = key 400*cda5da8dSAndroid Build Coastguard Worker return key 401*cda5da8dSAndroid Build Coastguard Worker 402*cda5da8dSAndroid Build Coastguard Worker def select(self, timeout=None): 403*cda5da8dSAndroid Build Coastguard Worker # This is shared between poll() and epoll(). 404*cda5da8dSAndroid Build Coastguard Worker # epoll() has a different signature and handling of timeout parameter. 405*cda5da8dSAndroid Build Coastguard Worker if timeout is None: 406*cda5da8dSAndroid Build Coastguard Worker timeout = None 407*cda5da8dSAndroid Build Coastguard Worker elif timeout <= 0: 408*cda5da8dSAndroid Build Coastguard Worker timeout = 0 409*cda5da8dSAndroid Build Coastguard Worker else: 410*cda5da8dSAndroid Build Coastguard Worker # poll() has a resolution of 1 millisecond, round away from 411*cda5da8dSAndroid Build Coastguard Worker # zero to wait *at least* timeout seconds. 412*cda5da8dSAndroid Build Coastguard Worker timeout = math.ceil(timeout * 1e3) 413*cda5da8dSAndroid Build Coastguard Worker ready = [] 414*cda5da8dSAndroid Build Coastguard Worker try: 415*cda5da8dSAndroid Build Coastguard Worker fd_event_list = self._selector.poll(timeout) 416*cda5da8dSAndroid Build Coastguard Worker except InterruptedError: 417*cda5da8dSAndroid Build Coastguard Worker return ready 418*cda5da8dSAndroid Build Coastguard Worker for fd, event in fd_event_list: 419*cda5da8dSAndroid Build Coastguard Worker events = 0 420*cda5da8dSAndroid Build Coastguard Worker if event & ~self._EVENT_READ: 421*cda5da8dSAndroid Build Coastguard Worker events |= EVENT_WRITE 422*cda5da8dSAndroid Build Coastguard Worker if event & ~self._EVENT_WRITE: 423*cda5da8dSAndroid Build Coastguard Worker events |= EVENT_READ 424*cda5da8dSAndroid Build Coastguard Worker 425*cda5da8dSAndroid Build Coastguard Worker key = self._key_from_fd(fd) 426*cda5da8dSAndroid Build Coastguard Worker if key: 427*cda5da8dSAndroid Build Coastguard Worker ready.append((key, events & key.events)) 428*cda5da8dSAndroid Build Coastguard Worker return ready 429*cda5da8dSAndroid Build Coastguard Worker 430*cda5da8dSAndroid Build Coastguard Worker 431*cda5da8dSAndroid Build Coastguard Workerif hasattr(select, 'poll'): 432*cda5da8dSAndroid Build Coastguard Worker 433*cda5da8dSAndroid Build Coastguard Worker class PollSelector(_PollLikeSelector): 434*cda5da8dSAndroid Build Coastguard Worker """Poll-based selector.""" 435*cda5da8dSAndroid Build Coastguard Worker _selector_cls = select.poll 436*cda5da8dSAndroid Build Coastguard Worker _EVENT_READ = select.POLLIN 437*cda5da8dSAndroid Build Coastguard Worker _EVENT_WRITE = select.POLLOUT 438*cda5da8dSAndroid Build Coastguard Worker 439*cda5da8dSAndroid Build Coastguard Worker 440*cda5da8dSAndroid Build Coastguard Workerif hasattr(select, 'epoll'): 441*cda5da8dSAndroid Build Coastguard Worker 442*cda5da8dSAndroid Build Coastguard Worker class EpollSelector(_PollLikeSelector): 443*cda5da8dSAndroid Build Coastguard Worker """Epoll-based selector.""" 444*cda5da8dSAndroid Build Coastguard Worker _selector_cls = select.epoll 445*cda5da8dSAndroid Build Coastguard Worker _EVENT_READ = select.EPOLLIN 446*cda5da8dSAndroid Build Coastguard Worker _EVENT_WRITE = select.EPOLLOUT 447*cda5da8dSAndroid Build Coastguard Worker 448*cda5da8dSAndroid Build Coastguard Worker def fileno(self): 449*cda5da8dSAndroid Build Coastguard Worker return self._selector.fileno() 450*cda5da8dSAndroid Build Coastguard Worker 451*cda5da8dSAndroid Build Coastguard Worker def select(self, timeout=None): 452*cda5da8dSAndroid Build Coastguard Worker if timeout is None: 453*cda5da8dSAndroid Build Coastguard Worker timeout = -1 454*cda5da8dSAndroid Build Coastguard Worker elif timeout <= 0: 455*cda5da8dSAndroid Build Coastguard Worker timeout = 0 456*cda5da8dSAndroid Build Coastguard Worker else: 457*cda5da8dSAndroid Build Coastguard Worker # epoll_wait() has a resolution of 1 millisecond, round away 458*cda5da8dSAndroid Build Coastguard Worker # from zero to wait *at least* timeout seconds. 459*cda5da8dSAndroid Build Coastguard Worker timeout = math.ceil(timeout * 1e3) * 1e-3 460*cda5da8dSAndroid Build Coastguard Worker 461*cda5da8dSAndroid Build Coastguard Worker # epoll_wait() expects `maxevents` to be greater than zero; 462*cda5da8dSAndroid Build Coastguard Worker # we want to make sure that `select()` can be called when no 463*cda5da8dSAndroid Build Coastguard Worker # FD is registered. 464*cda5da8dSAndroid Build Coastguard Worker max_ev = max(len(self._fd_to_key), 1) 465*cda5da8dSAndroid Build Coastguard Worker 466*cda5da8dSAndroid Build Coastguard Worker ready = [] 467*cda5da8dSAndroid Build Coastguard Worker try: 468*cda5da8dSAndroid Build Coastguard Worker fd_event_list = self._selector.poll(timeout, max_ev) 469*cda5da8dSAndroid Build Coastguard Worker except InterruptedError: 470*cda5da8dSAndroid Build Coastguard Worker return ready 471*cda5da8dSAndroid Build Coastguard Worker for fd, event in fd_event_list: 472*cda5da8dSAndroid Build Coastguard Worker events = 0 473*cda5da8dSAndroid Build Coastguard Worker if event & ~select.EPOLLIN: 474*cda5da8dSAndroid Build Coastguard Worker events |= EVENT_WRITE 475*cda5da8dSAndroid Build Coastguard Worker if event & ~select.EPOLLOUT: 476*cda5da8dSAndroid Build Coastguard Worker events |= EVENT_READ 477*cda5da8dSAndroid Build Coastguard Worker 478*cda5da8dSAndroid Build Coastguard Worker key = self._key_from_fd(fd) 479*cda5da8dSAndroid Build Coastguard Worker if key: 480*cda5da8dSAndroid Build Coastguard Worker ready.append((key, events & key.events)) 481*cda5da8dSAndroid Build Coastguard Worker return ready 482*cda5da8dSAndroid Build Coastguard Worker 483*cda5da8dSAndroid Build Coastguard Worker def close(self): 484*cda5da8dSAndroid Build Coastguard Worker self._selector.close() 485*cda5da8dSAndroid Build Coastguard Worker super().close() 486*cda5da8dSAndroid Build Coastguard Worker 487*cda5da8dSAndroid Build Coastguard Worker 488*cda5da8dSAndroid Build Coastguard Workerif hasattr(select, 'devpoll'): 489*cda5da8dSAndroid Build Coastguard Worker 490*cda5da8dSAndroid Build Coastguard Worker class DevpollSelector(_PollLikeSelector): 491*cda5da8dSAndroid Build Coastguard Worker """Solaris /dev/poll selector.""" 492*cda5da8dSAndroid Build Coastguard Worker _selector_cls = select.devpoll 493*cda5da8dSAndroid Build Coastguard Worker _EVENT_READ = select.POLLIN 494*cda5da8dSAndroid Build Coastguard Worker _EVENT_WRITE = select.POLLOUT 495*cda5da8dSAndroid Build Coastguard Worker 496*cda5da8dSAndroid Build Coastguard Worker def fileno(self): 497*cda5da8dSAndroid Build Coastguard Worker return self._selector.fileno() 498*cda5da8dSAndroid Build Coastguard Worker 499*cda5da8dSAndroid Build Coastguard Worker def close(self): 500*cda5da8dSAndroid Build Coastguard Worker self._selector.close() 501*cda5da8dSAndroid Build Coastguard Worker super().close() 502*cda5da8dSAndroid Build Coastguard Worker 503*cda5da8dSAndroid Build Coastguard Worker 504*cda5da8dSAndroid Build Coastguard Workerif hasattr(select, 'kqueue'): 505*cda5da8dSAndroid Build Coastguard Worker 506*cda5da8dSAndroid Build Coastguard Worker class KqueueSelector(_BaseSelectorImpl): 507*cda5da8dSAndroid Build Coastguard Worker """Kqueue-based selector.""" 508*cda5da8dSAndroid Build Coastguard Worker 509*cda5da8dSAndroid Build Coastguard Worker def __init__(self): 510*cda5da8dSAndroid Build Coastguard Worker super().__init__() 511*cda5da8dSAndroid Build Coastguard Worker self._selector = select.kqueue() 512*cda5da8dSAndroid Build Coastguard Worker 513*cda5da8dSAndroid Build Coastguard Worker def fileno(self): 514*cda5da8dSAndroid Build Coastguard Worker return self._selector.fileno() 515*cda5da8dSAndroid Build Coastguard Worker 516*cda5da8dSAndroid Build Coastguard Worker def register(self, fileobj, events, data=None): 517*cda5da8dSAndroid Build Coastguard Worker key = super().register(fileobj, events, data) 518*cda5da8dSAndroid Build Coastguard Worker try: 519*cda5da8dSAndroid Build Coastguard Worker if events & EVENT_READ: 520*cda5da8dSAndroid Build Coastguard Worker kev = select.kevent(key.fd, select.KQ_FILTER_READ, 521*cda5da8dSAndroid Build Coastguard Worker select.KQ_EV_ADD) 522*cda5da8dSAndroid Build Coastguard Worker self._selector.control([kev], 0, 0) 523*cda5da8dSAndroid Build Coastguard Worker if events & EVENT_WRITE: 524*cda5da8dSAndroid Build Coastguard Worker kev = select.kevent(key.fd, select.KQ_FILTER_WRITE, 525*cda5da8dSAndroid Build Coastguard Worker select.KQ_EV_ADD) 526*cda5da8dSAndroid Build Coastguard Worker self._selector.control([kev], 0, 0) 527*cda5da8dSAndroid Build Coastguard Worker except: 528*cda5da8dSAndroid Build Coastguard Worker super().unregister(fileobj) 529*cda5da8dSAndroid Build Coastguard Worker raise 530*cda5da8dSAndroid Build Coastguard Worker return key 531*cda5da8dSAndroid Build Coastguard Worker 532*cda5da8dSAndroid Build Coastguard Worker def unregister(self, fileobj): 533*cda5da8dSAndroid Build Coastguard Worker key = super().unregister(fileobj) 534*cda5da8dSAndroid Build Coastguard Worker if key.events & EVENT_READ: 535*cda5da8dSAndroid Build Coastguard Worker kev = select.kevent(key.fd, select.KQ_FILTER_READ, 536*cda5da8dSAndroid Build Coastguard Worker select.KQ_EV_DELETE) 537*cda5da8dSAndroid Build Coastguard Worker try: 538*cda5da8dSAndroid Build Coastguard Worker self._selector.control([kev], 0, 0) 539*cda5da8dSAndroid Build Coastguard Worker except OSError: 540*cda5da8dSAndroid Build Coastguard Worker # This can happen if the FD was closed since it 541*cda5da8dSAndroid Build Coastguard Worker # was registered. 542*cda5da8dSAndroid Build Coastguard Worker pass 543*cda5da8dSAndroid Build Coastguard Worker if key.events & EVENT_WRITE: 544*cda5da8dSAndroid Build Coastguard Worker kev = select.kevent(key.fd, select.KQ_FILTER_WRITE, 545*cda5da8dSAndroid Build Coastguard Worker select.KQ_EV_DELETE) 546*cda5da8dSAndroid Build Coastguard Worker try: 547*cda5da8dSAndroid Build Coastguard Worker self._selector.control([kev], 0, 0) 548*cda5da8dSAndroid Build Coastguard Worker except OSError: 549*cda5da8dSAndroid Build Coastguard Worker # See comment above. 550*cda5da8dSAndroid Build Coastguard Worker pass 551*cda5da8dSAndroid Build Coastguard Worker return key 552*cda5da8dSAndroid Build Coastguard Worker 553*cda5da8dSAndroid Build Coastguard Worker def select(self, timeout=None): 554*cda5da8dSAndroid Build Coastguard Worker timeout = None if timeout is None else max(timeout, 0) 555*cda5da8dSAndroid Build Coastguard Worker # If max_ev is 0, kqueue will ignore the timeout. For consistent 556*cda5da8dSAndroid Build Coastguard Worker # behavior with the other selector classes, we prevent that here 557*cda5da8dSAndroid Build Coastguard Worker # (using max). See https://bugs.python.org/issue29255 558*cda5da8dSAndroid Build Coastguard Worker max_ev = max(len(self._fd_to_key), 1) 559*cda5da8dSAndroid Build Coastguard Worker ready = [] 560*cda5da8dSAndroid Build Coastguard Worker try: 561*cda5da8dSAndroid Build Coastguard Worker kev_list = self._selector.control(None, max_ev, timeout) 562*cda5da8dSAndroid Build Coastguard Worker except InterruptedError: 563*cda5da8dSAndroid Build Coastguard Worker return ready 564*cda5da8dSAndroid Build Coastguard Worker for kev in kev_list: 565*cda5da8dSAndroid Build Coastguard Worker fd = kev.ident 566*cda5da8dSAndroid Build Coastguard Worker flag = kev.filter 567*cda5da8dSAndroid Build Coastguard Worker events = 0 568*cda5da8dSAndroid Build Coastguard Worker if flag == select.KQ_FILTER_READ: 569*cda5da8dSAndroid Build Coastguard Worker events |= EVENT_READ 570*cda5da8dSAndroid Build Coastguard Worker if flag == select.KQ_FILTER_WRITE: 571*cda5da8dSAndroid Build Coastguard Worker events |= EVENT_WRITE 572*cda5da8dSAndroid Build Coastguard Worker 573*cda5da8dSAndroid Build Coastguard Worker key = self._key_from_fd(fd) 574*cda5da8dSAndroid Build Coastguard Worker if key: 575*cda5da8dSAndroid Build Coastguard Worker ready.append((key, events & key.events)) 576*cda5da8dSAndroid Build Coastguard Worker return ready 577*cda5da8dSAndroid Build Coastguard Worker 578*cda5da8dSAndroid Build Coastguard Worker def close(self): 579*cda5da8dSAndroid Build Coastguard Worker self._selector.close() 580*cda5da8dSAndroid Build Coastguard Worker super().close() 581*cda5da8dSAndroid Build Coastguard Worker 582*cda5da8dSAndroid Build Coastguard Worker 583*cda5da8dSAndroid Build Coastguard Workerdef _can_use(method): 584*cda5da8dSAndroid Build Coastguard Worker """Check if we can use the selector depending upon the 585*cda5da8dSAndroid Build Coastguard Worker operating system. """ 586*cda5da8dSAndroid Build Coastguard Worker # Implementation based upon https://github.com/sethmlarson/selectors2/blob/master/selectors2.py 587*cda5da8dSAndroid Build Coastguard Worker selector = getattr(select, method, None) 588*cda5da8dSAndroid Build Coastguard Worker if selector is None: 589*cda5da8dSAndroid Build Coastguard Worker # select module does not implement method 590*cda5da8dSAndroid Build Coastguard Worker return False 591*cda5da8dSAndroid Build Coastguard Worker # check if the OS and Kernel actually support the method. Call may fail with 592*cda5da8dSAndroid Build Coastguard Worker # OSError: [Errno 38] Function not implemented 593*cda5da8dSAndroid Build Coastguard Worker try: 594*cda5da8dSAndroid Build Coastguard Worker selector_obj = selector() 595*cda5da8dSAndroid Build Coastguard Worker if method == 'poll': 596*cda5da8dSAndroid Build Coastguard Worker # check that poll actually works 597*cda5da8dSAndroid Build Coastguard Worker selector_obj.poll(0) 598*cda5da8dSAndroid Build Coastguard Worker else: 599*cda5da8dSAndroid Build Coastguard Worker # close epoll, kqueue, and devpoll fd 600*cda5da8dSAndroid Build Coastguard Worker selector_obj.close() 601*cda5da8dSAndroid Build Coastguard Worker return True 602*cda5da8dSAndroid Build Coastguard Worker except OSError: 603*cda5da8dSAndroid Build Coastguard Worker return False 604*cda5da8dSAndroid Build Coastguard Worker 605*cda5da8dSAndroid Build Coastguard Worker 606*cda5da8dSAndroid Build Coastguard Worker# Choose the best implementation, roughly: 607*cda5da8dSAndroid Build Coastguard Worker# epoll|kqueue|devpoll > poll > select. 608*cda5da8dSAndroid Build Coastguard Worker# select() also can't accept a FD > FD_SETSIZE (usually around 1024) 609*cda5da8dSAndroid Build Coastguard Workerif _can_use('kqueue'): 610*cda5da8dSAndroid Build Coastguard Worker DefaultSelector = KqueueSelector 611*cda5da8dSAndroid Build Coastguard Workerelif _can_use('epoll'): 612*cda5da8dSAndroid Build Coastguard Worker DefaultSelector = EpollSelector 613*cda5da8dSAndroid Build Coastguard Workerelif _can_use('devpoll'): 614*cda5da8dSAndroid Build Coastguard Worker DefaultSelector = DevpollSelector 615*cda5da8dSAndroid Build Coastguard Workerelif _can_use('poll'): 616*cda5da8dSAndroid Build Coastguard Worker DefaultSelector = PollSelector 617*cda5da8dSAndroid Build Coastguard Workerelse: 618*cda5da8dSAndroid Build Coastguard Worker DefaultSelector = SelectSelector 619