blob: f29d11fc6a87af3e7099eb741da9cc9e68884487 [file] [log] [blame]
Charles-François Natali243d8d82013-09-04 19:02:49 +02001"""Selectors module.
2
3This module allows high-level and efficient I/O multiplexing, built upon the
4`select` module primitives.
5"""
6
7
Victor Stinnerda492a82014-02-20 10:37:27 +01008from abc import ABCMeta, abstractmethod
Serhiy Storchaka2e576f52017-04-24 09:05:00 +03009from collections import namedtuple
10from collections.abc import Mapping
Victor Stinnerdcd97402014-01-31 12:12:53 +010011import math
Charles-François Natali243d8d82013-09-04 19:02:49 +020012import select
13import sys
14
15
16# generic events, that must be mapped to implementation-specific ones
17EVENT_READ = (1 << 0)
18EVENT_WRITE = (1 << 1)
19
20
21def _fileobj_to_fd(fileobj):
22 """Return a file descriptor from a file object.
23
24 Parameters:
25 fileobj -- file object or file descriptor
26
27 Returns:
28 corresponding file descriptor
Guido van Rossum9710ff02013-12-07 15:57:01 -080029
30 Raises:
31 ValueError if the object is invalid
Charles-François Natali243d8d82013-09-04 19:02:49 +020032 """
33 if isinstance(fileobj, int):
34 fd = fileobj
35 else:
36 try:
37 fd = int(fileobj.fileno())
38 except (AttributeError, TypeError, ValueError):
39 raise ValueError("Invalid file object: "
40 "{!r}".format(fileobj)) from None
41 if fd < 0:
42 raise ValueError("Invalid file descriptor: {}".format(fd))
43 return fd
44
45
46SelectorKey = namedtuple('SelectorKey', ['fileobj', 'fd', 'events', 'data'])
Charles-François Natali243d8d82013-09-04 19:02:49 +020047
Yury Selivanov0c6a3442016-03-02 10:37:59 -050048SelectorKey.__doc__ = """SelectorKey(fileobj, fd, events, data)
49
50 Object used to associate a file object to its backing
51 file descriptor, selected event mask, and attached data.
52"""
53if sys.version_info >= (3, 5):
54 SelectorKey.fileobj.__doc__ = 'File object registered.'
55 SelectorKey.fd.__doc__ = 'Underlying file descriptor.'
56 SelectorKey.events.__doc__ = 'Events that must be waited for on this file object.'
57 SelectorKey.data.__doc__ = ('''Optional opaque data associated to this file object.
58 For example, this could be used to store a per-client session ID.''')
Charles-François Natali243d8d82013-09-04 19:02:49 +020059
Charles-François Natali4574b492013-10-30 20:31:04 +010060class _SelectorMapping(Mapping):
61 """Mapping of file objects to selector keys."""
62
63 def __init__(self, selector):
64 self._selector = selector
65
66 def __len__(self):
67 return len(self._selector._fd_to_key)
68
69 def __getitem__(self, fileobj):
70 try:
Guido van Rossum9710ff02013-12-07 15:57:01 -080071 fd = self._selector._fileobj_lookup(fileobj)
72 return self._selector._fd_to_key[fd]
Charles-François Natali4574b492013-10-30 20:31:04 +010073 except KeyError:
74 raise KeyError("{!r} is not registered".format(fileobj)) from None
75
76 def __iter__(self):
77 return iter(self._selector._fd_to_key)
78
79
Charles-François Natali243d8d82013-09-04 19:02:49 +020080class BaseSelector(metaclass=ABCMeta):
Charles-François Natalib3330a0a2013-12-01 11:04:17 +010081 """Selector abstract base class.
Charles-François Natali243d8d82013-09-04 19:02:49 +020082
83 A selector supports registering file objects to be monitored for specific
84 I/O events.
85
86 A file object is a file descriptor or any object with a `fileno()` method.
87 An arbitrary object can be attached to the file object, which can be used
88 for example to store context information, a callback, etc.
89
90 A selector can use various implementations (select(), poll(), epoll()...)
91 depending on the platform. The default `Selector` class uses the most
Yury Selivanovb0b0e622014-02-18 22:27:48 -050092 efficient implementation on the current platform.
Charles-François Natali243d8d82013-09-04 19:02:49 +020093 """
94
Charles-François Natalib3330a0a2013-12-01 11:04:17 +010095 @abstractmethod
Charles-François Natali243d8d82013-09-04 19:02:49 +020096 def register(self, fileobj, events, data=None):
97 """Register a file object.
98
99 Parameters:
100 fileobj -- file object or file descriptor
101 events -- events to monitor (bitwise mask of EVENT_READ|EVENT_WRITE)
102 data -- attached data
103
104 Returns:
105 SelectorKey instance
Guido van Rossum9710ff02013-12-07 15:57:01 -0800106
107 Raises:
108 ValueError if events is invalid
109 KeyError if fileobj is already registered
110 OSError if fileobj is closed or otherwise is unacceptable to
111 the underlying system call (if a system call is made)
112
113 Note:
114 OSError may or may not be raised
Charles-François Natali243d8d82013-09-04 19:02:49 +0200115 """
Charles-François Natalib3330a0a2013-12-01 11:04:17 +0100116 raise NotImplementedError
Charles-François Natali243d8d82013-09-04 19:02:49 +0200117
Charles-François Natalib3330a0a2013-12-01 11:04:17 +0100118 @abstractmethod
Charles-François Natali243d8d82013-09-04 19:02:49 +0200119 def unregister(self, fileobj):
120 """Unregister a file object.
121
122 Parameters:
123 fileobj -- file object or file descriptor
124
125 Returns:
126 SelectorKey instance
Guido van Rossum9710ff02013-12-07 15:57:01 -0800127
128 Raises:
129 KeyError if fileobj is not registered
130
131 Note:
132 If fileobj is registered but has since been closed this does
133 *not* raise OSError (even if the wrapped syscall does)
Charles-François Natali243d8d82013-09-04 19:02:49 +0200134 """
Charles-François Natalib3330a0a2013-12-01 11:04:17 +0100135 raise NotImplementedError
Charles-François Natali243d8d82013-09-04 19:02:49 +0200136
137 def modify(self, fileobj, events, data=None):
138 """Change a registered file object monitored events or attached data.
139
140 Parameters:
141 fileobj -- file object or file descriptor
142 events -- events to monitor (bitwise mask of EVENT_READ|EVENT_WRITE)
143 data -- attached data
144
145 Returns:
146 SelectorKey instance
Guido van Rossum9710ff02013-12-07 15:57:01 -0800147
148 Raises:
149 Anything that unregister() or register() raises
Charles-François Natali243d8d82013-09-04 19:02:49 +0200150 """
Charles-François Natalib3330a0a2013-12-01 11:04:17 +0100151 self.unregister(fileobj)
152 return self.register(fileobj, events, data)
Charles-François Natali243d8d82013-09-04 19:02:49 +0200153
154 @abstractmethod
155 def select(self, timeout=None):
156 """Perform the actual selection, until some monitored file objects are
157 ready or a timeout expires.
158
159 Parameters:
160 timeout -- if timeout > 0, this specifies the maximum wait time, in
161 seconds
162 if timeout <= 0, the select() call won't block, and will
163 report the currently ready file objects
164 if timeout is None, select() will block until a monitored
165 file object becomes ready
166
167 Returns:
168 list of (key, events) for ready file objects
169 `events` is a bitwise mask of EVENT_READ|EVENT_WRITE
170 """
Charles-François Natalib3330a0a2013-12-01 11:04:17 +0100171 raise NotImplementedError
Charles-François Natali243d8d82013-09-04 19:02:49 +0200172
173 def close(self):
174 """Close the selector.
175
176 This must be called to make sure that any underlying resource is freed.
177 """
Charles-François Natalib3330a0a2013-12-01 11:04:17 +0100178 pass
Charles-François Natali243d8d82013-09-04 19:02:49 +0200179
180 def get_key(self, fileobj):
181 """Return the key associated to a registered file object.
182
183 Returns:
184 SelectorKey for this file object
185 """
Charles-François Natalib3330a0a2013-12-01 11:04:17 +0100186 mapping = self.get_map()
Victor Stinner458fc6f2015-01-13 10:00:55 +0100187 if mapping is None:
188 raise RuntimeError('Selector is closed')
Charles-François Natali243d8d82013-09-04 19:02:49 +0200189 try:
Charles-François Natalib3330a0a2013-12-01 11:04:17 +0100190 return mapping[fileobj]
Charles-François Natali243d8d82013-09-04 19:02:49 +0200191 except KeyError:
192 raise KeyError("{!r} is not registered".format(fileobj)) from None
193
Charles-François Natalib3330a0a2013-12-01 11:04:17 +0100194 @abstractmethod
Charles-François Natali4574b492013-10-30 20:31:04 +0100195 def get_map(self):
196 """Return a mapping of file objects to selector keys."""
Charles-François Natalib3330a0a2013-12-01 11:04:17 +0100197 raise NotImplementedError
Charles-François Natali4574b492013-10-30 20:31:04 +0100198
Charles-François Natali243d8d82013-09-04 19:02:49 +0200199 def __enter__(self):
200 return self
201
202 def __exit__(self, *args):
203 self.close()
204
Charles-François Natalib3330a0a2013-12-01 11:04:17 +0100205
206class _BaseSelectorImpl(BaseSelector):
207 """Base selector implementation."""
208
209 def __init__(self):
210 # this maps file descriptors to keys
211 self._fd_to_key = {}
212 # read-only mapping returned by get_map()
213 self._map = _SelectorMapping(self)
214
Guido van Rossum9710ff02013-12-07 15:57:01 -0800215 def _fileobj_lookup(self, fileobj):
216 """Return a file descriptor from a file object.
217
218 This wraps _fileobj_to_fd() to do an exhaustive search in case
219 the object is invalid but we still have it in our map. This
220 is used by unregister() so we can unregister an object that
221 was previously registered even if it is closed. It is also
222 used by _SelectorMapping.
223 """
224 try:
225 return _fileobj_to_fd(fileobj)
226 except ValueError:
227 # Do an exhaustive search.
228 for key in self._fd_to_key.values():
229 if key.fileobj is fileobj:
230 return key.fd
231 # Raise ValueError after all.
232 raise
233
Charles-François Natalib3330a0a2013-12-01 11:04:17 +0100234 def register(self, fileobj, events, data=None):
235 if (not events) or (events & ~(EVENT_READ | EVENT_WRITE)):
236 raise ValueError("Invalid events: {!r}".format(events))
237
Guido van Rossum9710ff02013-12-07 15:57:01 -0800238 key = SelectorKey(fileobj, self._fileobj_lookup(fileobj), events, data)
Charles-François Natalib3330a0a2013-12-01 11:04:17 +0100239
240 if key.fd in self._fd_to_key:
Guido van Rossum9710ff02013-12-07 15:57:01 -0800241 raise KeyError("{!r} (FD {}) is already registered"
242 .format(fileobj, key.fd))
Charles-François Natalib3330a0a2013-12-01 11:04:17 +0100243
244 self._fd_to_key[key.fd] = key
245 return key
246
247 def unregister(self, fileobj):
248 try:
Guido van Rossum9710ff02013-12-07 15:57:01 -0800249 key = self._fd_to_key.pop(self._fileobj_lookup(fileobj))
Charles-François Natalib3330a0a2013-12-01 11:04:17 +0100250 except KeyError:
251 raise KeyError("{!r} is not registered".format(fileobj)) from None
252 return key
253
254 def modify(self, fileobj, events, data=None):
255 # TODO: Subclasses can probably optimize this even further.
256 try:
Guido van Rossum9710ff02013-12-07 15:57:01 -0800257 key = self._fd_to_key[self._fileobj_lookup(fileobj)]
Charles-François Natalib3330a0a2013-12-01 11:04:17 +0100258 except KeyError:
259 raise KeyError("{!r} is not registered".format(fileobj)) from None
260 if events != key.events:
261 self.unregister(fileobj)
262 key = self.register(fileobj, events, data)
263 elif data != key.data:
264 # Use a shortcut to update the data.
265 key = key._replace(data=data)
266 self._fd_to_key[key.fd] = key
267 return key
268
269 def close(self):
270 self._fd_to_key.clear()
Victor Stinner38dc2502015-01-13 09:58:33 +0100271 self._map = None
Charles-François Natalib3330a0a2013-12-01 11:04:17 +0100272
273 def get_map(self):
274 return self._map
275
Charles-François Natali243d8d82013-09-04 19:02:49 +0200276 def _key_from_fd(self, fd):
277 """Return the key associated to a given file descriptor.
278
279 Parameters:
280 fd -- file descriptor
281
282 Returns:
283 corresponding key, or None if not found
284 """
285 try:
286 return self._fd_to_key[fd]
287 except KeyError:
288 return None
289
290
Charles-François Natalib3330a0a2013-12-01 11:04:17 +0100291class SelectSelector(_BaseSelectorImpl):
Charles-François Natali243d8d82013-09-04 19:02:49 +0200292 """Select-based selector."""
293
294 def __init__(self):
295 super().__init__()
296 self._readers = set()
297 self._writers = set()
298
299 def register(self, fileobj, events, data=None):
300 key = super().register(fileobj, events, data)
301 if events & EVENT_READ:
302 self._readers.add(key.fd)
303 if events & EVENT_WRITE:
304 self._writers.add(key.fd)
305 return key
306
307 def unregister(self, fileobj):
308 key = super().unregister(fileobj)
309 self._readers.discard(key.fd)
310 self._writers.discard(key.fd)
311 return key
312
313 if sys.platform == 'win32':
314 def _select(self, r, w, _, timeout=None):
315 r, w, x = select.select(r, w, w, timeout)
316 return r, w + x, []
317 else:
318 _select = select.select
319
320 def select(self, timeout=None):
321 timeout = None if timeout is None else max(timeout, 0)
322 ready = []
Yury Selivanov90ecfe62015-05-11 13:48:16 -0400323 try:
324 r, w, _ = self._select(self._readers, self._writers, [], timeout)
325 except InterruptedError:
326 return ready
Charles-François Natali243d8d82013-09-04 19:02:49 +0200327 r = set(r)
328 w = set(w)
329 for fd in r | w:
330 events = 0
331 if fd in r:
332 events |= EVENT_READ
333 if fd in w:
334 events |= EVENT_WRITE
335
336 key = self._key_from_fd(fd)
337 if key:
338 ready.append((key, events & key.events))
339 return ready
340
341
Giampaolo Rodola62c7d902017-05-20 11:34:44 +0200342class _PollLikeSelector(_BaseSelectorImpl):
343 """Base class shared between poll, epoll and devpoll selectors."""
344 _selector_cls = None
345
346 def __init__(self):
347 super().__init__()
348 self._selector = self._selector_cls()
349
350 def register(self, fileobj, events, data=None):
351 key = super().register(fileobj, events, data)
352 poller_events = 0
353 if events & EVENT_READ:
354 poller_events |= self._EVENT_READ
355 if events & EVENT_WRITE:
356 poller_events |= self._EVENT_WRITE
357 try:
358 self._selector.register(key.fd, poller_events)
359 except Exception:
360 super().unregister(fileobj)
361 raise
362 return key
363
364 def unregister(self, fileobj):
365 key = super().unregister(fileobj)
366 try:
367 self._selector.unregister(key.fd)
368 except OSError:
369 # This can happen if the FD was closed since it
370 # was registered.
371 pass
372 return key
373
374 def select(self, timeout=None):
375 # This is shared between poll() and epoll().
376 # epoll() has a different signature and handling of timeout parameter.
377 if timeout is None:
378 timeout = None
379 elif timeout <= 0:
380 timeout = 0
381 else:
382 # poll() has a resolution of 1 millisecond, round away from
383 # zero to wait *at least* timeout seconds.
384 timeout = math.ceil(timeout * 1e3)
385 ready = []
386 try:
387 fd_event_list = self._selector.poll(timeout)
388 except InterruptedError:
389 return ready
390 for fd, event in fd_event_list:
391 events = 0
392 if event & ~self._EVENT_READ:
393 events |= EVENT_WRITE
394 if event & ~self._EVENT_WRITE:
395 events |= EVENT_READ
396
397 key = self._key_from_fd(fd)
398 if key:
399 ready.append((key, events & key.events))
400 return ready
401
402
Charles-François Natali243d8d82013-09-04 19:02:49 +0200403if hasattr(select, 'poll'):
404
Giampaolo Rodola62c7d902017-05-20 11:34:44 +0200405 class PollSelector(_PollLikeSelector):
Charles-François Natali243d8d82013-09-04 19:02:49 +0200406 """Poll-based selector."""
Giampaolo Rodola62c7d902017-05-20 11:34:44 +0200407 _selector_cls = select.poll
408 _EVENT_READ = select.POLLIN
409 _EVENT_WRITE = select.POLLOUT
Charles-François Natali243d8d82013-09-04 19:02:49 +0200410
411
412if hasattr(select, 'epoll'):
413
Giampaolo Rodola62c7d902017-05-20 11:34:44 +0200414 class EpollSelector(_PollLikeSelector):
Charles-François Natali243d8d82013-09-04 19:02:49 +0200415 """Epoll-based selector."""
Giampaolo Rodola62c7d902017-05-20 11:34:44 +0200416 _selector_cls = select.epoll
417 _EVENT_READ = select.EPOLLIN
418 _EVENT_WRITE = select.EPOLLOUT
Charles-François Natali243d8d82013-09-04 19:02:49 +0200419
420 def fileno(self):
Giampaolo Rodola62c7d902017-05-20 11:34:44 +0200421 return self._selector.fileno()
Charles-François Natali243d8d82013-09-04 19:02:49 +0200422
423 def select(self, timeout=None):
Victor Stinner567b26e2014-01-21 21:00:47 +0100424 if timeout is None:
425 timeout = -1
426 elif timeout <= 0:
427 timeout = 0
Victor Stinnerdcd97402014-01-31 12:12:53 +0100428 else:
429 # epoll_wait() has a resolution of 1 millisecond, round away
430 # from zero to wait *at least* timeout seconds.
431 timeout = math.ceil(timeout * 1e3) * 1e-3
Yury Selivanovd60ef4a2014-12-08 12:21:58 -0500432
Yury Selivanovdfc44e02014-12-08 12:30:10 -0500433 # epoll_wait() expects `maxevents` to be greater than zero;
Yury Selivanovd60ef4a2014-12-08 12:21:58 -0500434 # we want to make sure that `select()` can be called when no
435 # FD is registered.
436 max_ev = max(len(self._fd_to_key), 1)
437
Charles-François Natali243d8d82013-09-04 19:02:49 +0200438 ready = []
Yury Selivanov90ecfe62015-05-11 13:48:16 -0400439 try:
Giampaolo Rodola62c7d902017-05-20 11:34:44 +0200440 fd_event_list = self._selector.poll(timeout, max_ev)
Yury Selivanov90ecfe62015-05-11 13:48:16 -0400441 except InterruptedError:
442 return ready
Charles-François Natali243d8d82013-09-04 19:02:49 +0200443 for fd, event in fd_event_list:
444 events = 0
445 if event & ~select.EPOLLIN:
446 events |= EVENT_WRITE
447 if event & ~select.EPOLLOUT:
448 events |= EVENT_READ
449
450 key = self._key_from_fd(fd)
451 if key:
452 ready.append((key, events & key.events))
453 return ready
454
455 def close(self):
Giampaolo Rodola62c7d902017-05-20 11:34:44 +0200456 self._selector.close()
Yury Selivanov90ecfe62015-05-11 13:48:16 -0400457 super().close()
Charles-François Natali243d8d82013-09-04 19:02:49 +0200458
459
Giampaolo Rodola'f97e8292014-03-20 21:43:41 +0100460if hasattr(select, 'devpoll'):
461
Giampaolo Rodola62c7d902017-05-20 11:34:44 +0200462 class DevpollSelector(_PollLikeSelector):
Giampaolo Rodola'f97e8292014-03-20 21:43:41 +0100463 """Solaris /dev/poll selector."""
Giampaolo Rodola62c7d902017-05-20 11:34:44 +0200464 _selector_cls = select.devpoll
465 _EVENT_READ = select.POLLIN
466 _EVENT_WRITE = select.POLLOUT
Giampaolo Rodola'f97e8292014-03-20 21:43:41 +0100467
468 def fileno(self):
Giampaolo Rodola62c7d902017-05-20 11:34:44 +0200469 return self._selector.fileno()
Giampaolo Rodola'f97e8292014-03-20 21:43:41 +0100470
471 def close(self):
Giampaolo Rodola62c7d902017-05-20 11:34:44 +0200472 self._selector.close()
Yury Selivanov90ecfe62015-05-11 13:48:16 -0400473 super().close()
Giampaolo Rodola'f97e8292014-03-20 21:43:41 +0100474
475
Charles-François Natali243d8d82013-09-04 19:02:49 +0200476if hasattr(select, 'kqueue'):
477
Charles-François Natalib3330a0a2013-12-01 11:04:17 +0100478 class KqueueSelector(_BaseSelectorImpl):
Charles-François Natali243d8d82013-09-04 19:02:49 +0200479 """Kqueue-based selector."""
480
481 def __init__(self):
482 super().__init__()
Giampaolo Rodola62c7d902017-05-20 11:34:44 +0200483 self._selector = select.kqueue()
Charles-François Natali243d8d82013-09-04 19:02:49 +0200484
485 def fileno(self):
Giampaolo Rodola62c7d902017-05-20 11:34:44 +0200486 return self._selector.fileno()
Charles-François Natali243d8d82013-09-04 19:02:49 +0200487
488 def register(self, fileobj, events, data=None):
489 key = super().register(fileobj, events, data)
Yury Selivanov525aedc2016-09-15 19:30:42 -0400490 try:
491 if events & EVENT_READ:
492 kev = select.kevent(key.fd, select.KQ_FILTER_READ,
493 select.KQ_EV_ADD)
Giampaolo Rodola62c7d902017-05-20 11:34:44 +0200494 self._selector.control([kev], 0, 0)
Yury Selivanov525aedc2016-09-15 19:30:42 -0400495 if events & EVENT_WRITE:
496 kev = select.kevent(key.fd, select.KQ_FILTER_WRITE,
497 select.KQ_EV_ADD)
Giampaolo Rodola62c7d902017-05-20 11:34:44 +0200498 self._selector.control([kev], 0, 0)
499 except Exception:
Yury Selivanov525aedc2016-09-15 19:30:42 -0400500 super().unregister(fileobj)
501 raise
Charles-François Natali243d8d82013-09-04 19:02:49 +0200502 return key
503
504 def unregister(self, fileobj):
505 key = super().unregister(fileobj)
506 if key.events & EVENT_READ:
507 kev = select.kevent(key.fd, select.KQ_FILTER_READ,
508 select.KQ_EV_DELETE)
Guido van Rossum9710ff02013-12-07 15:57:01 -0800509 try:
Giampaolo Rodola62c7d902017-05-20 11:34:44 +0200510 self._selector.control([kev], 0, 0)
Guido van Rossum9710ff02013-12-07 15:57:01 -0800511 except OSError:
512 # This can happen if the FD was closed since it
513 # was registered.
514 pass
Charles-François Natali243d8d82013-09-04 19:02:49 +0200515 if key.events & EVENT_WRITE:
516 kev = select.kevent(key.fd, select.KQ_FILTER_WRITE,
517 select.KQ_EV_DELETE)
Guido van Rossum9710ff02013-12-07 15:57:01 -0800518 try:
Giampaolo Rodola62c7d902017-05-20 11:34:44 +0200519 self._selector.control([kev], 0, 0)
Guido van Rossum9710ff02013-12-07 15:57:01 -0800520 except OSError:
521 # See comment above.
522 pass
Charles-François Natali243d8d82013-09-04 19:02:49 +0200523 return key
524
525 def select(self, timeout=None):
526 timeout = None if timeout is None else max(timeout, 0)
527 max_ev = len(self._fd_to_key)
528 ready = []
Yury Selivanov90ecfe62015-05-11 13:48:16 -0400529 try:
Giampaolo Rodola62c7d902017-05-20 11:34:44 +0200530 kev_list = self._selector.control(None, max_ev, timeout)
Yury Selivanov90ecfe62015-05-11 13:48:16 -0400531 except InterruptedError:
532 return ready
Charles-François Natali243d8d82013-09-04 19:02:49 +0200533 for kev in kev_list:
534 fd = kev.ident
535 flag = kev.filter
536 events = 0
537 if flag == select.KQ_FILTER_READ:
538 events |= EVENT_READ
539 if flag == select.KQ_FILTER_WRITE:
540 events |= EVENT_WRITE
541
542 key = self._key_from_fd(fd)
543 if key:
544 ready.append((key, events & key.events))
545 return ready
546
547 def close(self):
Giampaolo Rodola62c7d902017-05-20 11:34:44 +0200548 self._selector.close()
Yury Selivanov90ecfe62015-05-11 13:48:16 -0400549 super().close()
Charles-François Natali243d8d82013-09-04 19:02:49 +0200550
551
Victor Stinner53a6d742015-01-09 00:13:39 +0100552# Choose the best implementation, roughly:
553# epoll|kqueue|devpoll > poll > select.
Charles-François Natali243d8d82013-09-04 19:02:49 +0200554# select() also can't accept a FD > FD_SETSIZE (usually around 1024)
555if 'KqueueSelector' in globals():
556 DefaultSelector = KqueueSelector
557elif 'EpollSelector' in globals():
558 DefaultSelector = EpollSelector
Giampaolo Rodola'f97e8292014-03-20 21:43:41 +0100559elif 'DevpollSelector' in globals():
560 DefaultSelector = DevpollSelector
Charles-François Natali243d8d82013-09-04 19:02:49 +0200561elif 'PollSelector' in globals():
562 DefaultSelector = PollSelector
563else:
564 DefaultSelector = SelectSelector