annotate mercurial/selectors2.py @ 34968:3649c3f2cd90

revert: do not reverse hunks in interactive when REV is not parent (issue5096) And introduce a new "apply" operation verb for this case as suggested in issue5096. This replaces the no longer used "revert" operation. In interactive revert, when reverting to something else that the parent revision, display an "apply this change" message with a diff that is not reversed. The rationale is that `hg revert -i -r REV` will show hunks of the diff from the working directory to REV and prompt the user to select them for applying (to working directory). This contradicts dcc56e10c23b in which it was decided to have the "direction" of prompted hunks reversed. Later on [1], there was a broad consensus (but no decision) towards the "as to be applied direction". Now that --interactive is no longer experimental (5910db5d1913), it's time to switch and thus we drop no longer used "experimental.revertalternateinteractivemode" configuration option. [1]: https://www.mercurial-scm.org/pipermail/mercurial-devel/2016-November/090142.html .. feature:: When interactive revert is run against a revision other than the working directory parent, the diff shown is the diff to *apply* to the working directory, rather than the diff to *discard* from the working copy. This is in line with related user experiences with `git` and appears to be less confusing with `ui.interface=curses`.
author Denis Laxalde <denis.laxalde@logilab.fr>
date Fri, 03 Nov 2017 14:47:37 +0100
parents a568a46751b6
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
33502
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
1 """ Back-ported, durable, and portable selectors """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
2
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
3 # MIT License
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
4 #
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
5 # Copyright (c) 2017 Seth Michael Larson
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
6 #
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
7 # Permission is hereby granted, free of charge, to any person obtaining a copy
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
8 # of this software and associated documentation files (the "Software"), to deal
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
9 # in the Software without restriction, including without limitation the rights
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
10 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
11 # copies of the Software, and to permit persons to whom the Software is
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
12 # furnished to do so, subject to the following conditions:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
13 #
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
14 # The above copyright notice and this permission notice shall be included in all
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
15 # copies or substantial portions of the Software.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
16 #
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
18 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
19 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
20 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
21 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
22 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
23 # SOFTWARE.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
24
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
25 # no-check-code
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
26
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
27 from __future__ import absolute_import
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
28
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
29 import collections
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
30 import errno
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
31 import math
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
32 import select
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
33 import socket
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
34 import sys
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
35 import time
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
36
34639
a568a46751b6 selectors2: do not use platform.system()
Jun Wu <quark@fb.com>
parents: 33502
diff changeset
37 from . import pycompat
a568a46751b6 selectors2: do not use platform.system()
Jun Wu <quark@fb.com>
parents: 33502
diff changeset
38
33502
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
39 namedtuple = collections.namedtuple
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
40 Mapping = collections.Mapping
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
41
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
42 try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
43 monotonic = time.monotonic
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
44 except AttributeError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
45 monotonic = time.time
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
46
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
47 __author__ = 'Seth Michael Larson'
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
48 __email__ = 'sethmichaellarson@protonmail.com'
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
49 __version__ = '2.0.0'
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
50 __license__ = 'MIT'
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
51 __url__ = 'https://www.github.com/SethMichaelLarson/selectors2'
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
52
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
53 __all__ = ['EVENT_READ',
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
54 'EVENT_WRITE',
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
55 'SelectorKey',
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
56 'DefaultSelector',
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
57 'BaseSelector']
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
58
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
59 EVENT_READ = (1 << 0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
60 EVENT_WRITE = (1 << 1)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
61 _DEFAULT_SELECTOR = None
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
62 _SYSCALL_SENTINEL = object() # Sentinel in case a system call returns None.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
63 _ERROR_TYPES = (OSError, IOError, socket.error)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
64
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
65
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
66 SelectorKey = namedtuple('SelectorKey', ['fileobj', 'fd', 'events', 'data'])
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
67
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
68
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
69 class _SelectorMapping(Mapping):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
70 """ Mapping of file objects to selector keys """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
71
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
72 def __init__(self, selector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
73 self._selector = selector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
74
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
75 def __len__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
76 return len(self._selector._fd_to_key)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
77
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
78 def __getitem__(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
79 try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
80 fd = self._selector._fileobj_lookup(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
81 return self._selector._fd_to_key[fd]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
82 except KeyError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
83 raise KeyError("{0!r} is not registered.".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
84
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
85 def __iter__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
86 return iter(self._selector._fd_to_key)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
87
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
88
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
89 def _fileobj_to_fd(fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
90 """ Return a file descriptor from a file object. If
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
91 given an integer will simply return that integer back. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
92 if isinstance(fileobj, int):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
93 fd = fileobj
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
94 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
95 try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
96 fd = int(fileobj.fileno())
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
97 except (AttributeError, TypeError, ValueError):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
98 raise ValueError("Invalid file object: {0!r}".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
99 if fd < 0:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
100 raise ValueError("Invalid file descriptor: {0}".format(fd))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
101 return fd
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
102
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
103
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
104 class BaseSelector(object):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
105 """ Abstract Selector class
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
106
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
107 A selector supports registering file objects to be monitored
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
108 for specific I/O events.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
109
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
110 A file object is a file descriptor or any object with a
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
111 `fileno()` method. An arbitrary object can be attached to the
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
112 file object which can be used for example to store context info,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
113 a callback, etc.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
114
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
115 A selector can use various implementations (select(), poll(), epoll(),
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
116 and kqueue()) depending on the platform. The 'DefaultSelector' class uses
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
117 the most efficient implementation for the current platform.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
118 """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
119 def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
120 # Maps file descriptors to keys.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
121 self._fd_to_key = {}
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
122
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
123 # Read-only mapping returned by get_map()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
124 self._map = _SelectorMapping(self)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
125
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
126 def _fileobj_lookup(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
127 """ Return a file descriptor from a file object.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
128 This wraps _fileobj_to_fd() to do an exhaustive
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
129 search in case the object is invalid but we still
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
130 have it in our map. Used by unregister() so we can
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
131 unregister an object that was previously registered
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
132 even if it is closed. It is also used by _SelectorMapping
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
133 """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
134 try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
135 return _fileobj_to_fd(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
136 except ValueError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
137
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
138 # Search through all our mapped keys.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
139 for key in self._fd_to_key.values():
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
140 if key.fileobj is fileobj:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
141 return key.fd
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
142
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
143 # Raise ValueError after all.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
144 raise
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
145
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
146 def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
147 """ Register a file object for a set of events to monitor. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
148 if (not events) or (events & ~(EVENT_READ | EVENT_WRITE)):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
149 raise ValueError("Invalid events: {0!r}".format(events))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
150
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
151 key = SelectorKey(fileobj, self._fileobj_lookup(fileobj), events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
152
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
153 if key.fd in self._fd_to_key:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
154 raise KeyError("{0!r} (FD {1}) is already registered"
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
155 .format(fileobj, key.fd))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
156
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
157 self._fd_to_key[key.fd] = key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
158 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
159
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
160 def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
161 """ Unregister a file object from being monitored. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
162 try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
163 key = self._fd_to_key.pop(self._fileobj_lookup(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
164 except KeyError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
165 raise KeyError("{0!r} is not registered".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
166
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
167 # Getting the fileno of a closed socket on Windows errors with EBADF.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
168 except socket.error as err:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
169 if err.errno != errno.EBADF:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
170 raise
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
171 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
172 for key in self._fd_to_key.values():
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
173 if key.fileobj is fileobj:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
174 self._fd_to_key.pop(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
175 break
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
176 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
177 raise KeyError("{0!r} is not registered".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
178 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
179
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
180 def modify(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
181 """ Change a registered file object monitored events and data. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
182 # NOTE: Some subclasses optimize this operation even further.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
183 try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
184 key = self._fd_to_key[self._fileobj_lookup(fileobj)]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
185 except KeyError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
186 raise KeyError("{0!r} is not registered".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
187
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
188 if events != key.events:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
189 self.unregister(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
190 key = self.register(fileobj, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
191
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
192 elif data != key.data:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
193 # Use a shortcut to update the data.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
194 key = key._replace(data=data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
195 self._fd_to_key[key.fd] = key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
196
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
197 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
198
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
199 def select(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
200 """ Perform the actual selection until some monitored file objects
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
201 are ready or the timeout expires. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
202 raise NotImplementedError()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
203
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
204 def close(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
205 """ Close the selector. This must be called to ensure that all
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
206 underlying resources are freed. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
207 self._fd_to_key.clear()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
208 self._map = None
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
209
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
210 def get_key(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
211 """ Return the key associated with a registered file object. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
212 mapping = self.get_map()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
213 if mapping is None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
214 raise RuntimeError("Selector is closed")
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
215 try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
216 return mapping[fileobj]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
217 except KeyError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
218 raise KeyError("{0!r} is not registered".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
219
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
220 def get_map(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
221 """ Return a mapping of file objects to selector keys """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
222 return self._map
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
223
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
224 def _key_from_fd(self, fd):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
225 """ Return the key associated to a given file descriptor
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
226 Return None if it is not found. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
227 try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
228 return self._fd_to_key[fd]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
229 except KeyError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
230 return None
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
231
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
232 def __enter__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
233 return self
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
234
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
235 def __exit__(self, *_):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
236 self.close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
237
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
238
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
239 # Almost all platforms have select.select()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
240 if hasattr(select, "select"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
241 class SelectSelector(BaseSelector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
242 """ Select-based selector. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
243 def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
244 super(SelectSelector, self).__init__()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
245 self._readers = set()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
246 self._writers = set()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
247
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
248 def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
249 key = super(SelectSelector, self).register(fileobj, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
250 if events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
251 self._readers.add(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
252 if events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
253 self._writers.add(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
254 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
255
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
256 def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
257 key = super(SelectSelector, self).unregister(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
258 self._readers.discard(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
259 self._writers.discard(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
260 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
261
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
262 def select(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
263 # Selecting on empty lists on Windows errors out.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
264 if not len(self._readers) and not len(self._writers):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
265 return []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
266
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
267 timeout = None if timeout is None else max(timeout, 0.0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
268 ready = []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
269 r, w, _ = _syscall_wrapper(self._wrap_select, True, self._readers,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
270 self._writers, timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
271 r = set(r)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
272 w = set(w)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
273 for fd in r | w:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
274 events = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
275 if fd in r:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
276 events |= EVENT_READ
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
277 if fd in w:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
278 events |= EVENT_WRITE
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
279
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
280 key = self._key_from_fd(fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
281 if key:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
282 ready.append((key, events & key.events))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
283 return ready
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
284
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
285 def _wrap_select(self, r, w, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
286 """ Wrapper for select.select because timeout is a positional arg """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
287 return select.select(r, w, [], timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
288
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
289 __all__.append('SelectSelector')
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
290
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
291 # Jython has a different implementation of .fileno() for socket objects.
34639
a568a46751b6 selectors2: do not use platform.system()
Jun Wu <quark@fb.com>
parents: 33502
diff changeset
292 if pycompat.isjython:
33502
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
293 class _JythonSelectorMapping(object):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
294 """ This is an implementation of _SelectorMapping that is built
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
295 for use specifically with Jython, which does not provide a hashable
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
296 value from socket.socket.fileno(). """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
297
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
298 def __init__(self, selector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
299 assert isinstance(selector, JythonSelectSelector)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
300 self._selector = selector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
301
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
302 def __len__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
303 return len(self._selector._sockets)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
304
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
305 def __getitem__(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
306 for sock, key in self._selector._sockets:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
307 if sock is fileobj:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
308 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
309 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
310 raise KeyError("{0!r} is not registered.".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
311
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
312 class JythonSelectSelector(SelectSelector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
313 """ This is an implementation of SelectSelector that is for Jython
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
314 which works around that Jython's socket.socket.fileno() does not
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
315 return an integer fd value. All SelectorKey.fd will be equal to -1
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
316 and should not be used. This instead uses object id to compare fileobj
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
317 and will only use select.select as it's the only selector that allows
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
318 directly passing in socket objects rather than registering fds.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
319 See: http://bugs.jython.org/issue1678
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
320 https://wiki.python.org/jython/NewSocketModule#socket.fileno.28.29_does_not_return_an_integer
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
321 """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
322
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
323 def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
324 super(JythonSelectSelector, self).__init__()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
325
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
326 self._sockets = [] # Uses a list of tuples instead of dictionary.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
327 self._map = _JythonSelectorMapping(self)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
328 self._readers = []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
329 self._writers = []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
330
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
331 # Jython has a select.cpython_compatible_select function in older versions.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
332 self._select_func = getattr(select, 'cpython_compatible_select', select.select)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
333
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
334 def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
335 for sock, _ in self._sockets:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
336 if sock is fileobj:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
337 raise KeyError("{0!r} is already registered"
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
338 .format(fileobj, sock))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
339
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
340 key = SelectorKey(fileobj, -1, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
341 self._sockets.append((fileobj, key))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
342
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
343 if events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
344 self._readers.append(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
345 if events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
346 self._writers.append(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
347 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
348
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
349 def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
350 for i, (sock, key) in enumerate(self._sockets):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
351 if sock is fileobj:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
352 break
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
353 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
354 raise KeyError("{0!r} is not registered.".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
355
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
356 if key.events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
357 self._readers.remove(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
358 if key.events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
359 self._writers.remove(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
360
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
361 del self._sockets[i]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
362 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
363
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
364 def _wrap_select(self, r, w, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
365 """ Wrapper for select.select because timeout is a positional arg """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
366 return self._select_func(r, w, [], timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
367
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
368 __all__.append('JythonSelectSelector')
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
369 SelectSelector = JythonSelectSelector # Override so the wrong selector isn't used.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
370
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
371
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
372 if hasattr(select, "poll"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
373 class PollSelector(BaseSelector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
374 """ Poll-based selector """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
375 def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
376 super(PollSelector, self).__init__()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
377 self._poll = select.poll()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
378
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
379 def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
380 key = super(PollSelector, self).register(fileobj, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
381 event_mask = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
382 if events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
383 event_mask |= select.POLLIN
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
384 if events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
385 event_mask |= select.POLLOUT
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
386 self._poll.register(key.fd, event_mask)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
387 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
388
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
389 def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
390 key = super(PollSelector, self).unregister(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
391 self._poll.unregister(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
392 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
393
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
394 def _wrap_poll(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
395 """ Wrapper function for select.poll.poll() so that
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
396 _syscall_wrapper can work with only seconds. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
397 if timeout is not None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
398 if timeout <= 0:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
399 timeout = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
400 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
401 # select.poll.poll() has a resolution of 1 millisecond,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
402 # round away from zero to wait *at least* timeout seconds.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
403 timeout = math.ceil(timeout * 1000)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
404
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
405 result = self._poll.poll(timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
406 return result
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
407
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
408 def select(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
409 ready = []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
410 fd_events = _syscall_wrapper(self._wrap_poll, True, timeout=timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
411 for fd, event_mask in fd_events:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
412 events = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
413 if event_mask & ~select.POLLIN:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
414 events |= EVENT_WRITE
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
415 if event_mask & ~select.POLLOUT:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
416 events |= EVENT_READ
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
417
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
418 key = self._key_from_fd(fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
419 if key:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
420 ready.append((key, events & key.events))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
421
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
422 return ready
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
423
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
424 __all__.append('PollSelector')
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
425
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
426 if hasattr(select, "epoll"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
427 class EpollSelector(BaseSelector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
428 """ Epoll-based selector """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
429 def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
430 super(EpollSelector, self).__init__()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
431 self._epoll = select.epoll()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
432
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
433 def fileno(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
434 return self._epoll.fileno()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
435
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
436 def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
437 key = super(EpollSelector, self).register(fileobj, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
438 events_mask = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
439 if events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
440 events_mask |= select.EPOLLIN
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
441 if events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
442 events_mask |= select.EPOLLOUT
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
443 _syscall_wrapper(self._epoll.register, False, key.fd, events_mask)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
444 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
445
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
446 def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
447 key = super(EpollSelector, self).unregister(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
448 try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
449 _syscall_wrapper(self._epoll.unregister, False, key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
450 except _ERROR_TYPES:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
451 # This can occur when the fd was closed since registry.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
452 pass
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
453 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
454
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
455 def select(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
456 if timeout is not None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
457 if timeout <= 0:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
458 timeout = 0.0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
459 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
460 # select.epoll.poll() has a resolution of 1 millisecond
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
461 # but luckily takes seconds so we don't need a wrapper
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
462 # like PollSelector. Just for better rounding.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
463 timeout = math.ceil(timeout * 1000) * 0.001
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
464 timeout = float(timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
465 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
466 timeout = -1.0 # epoll.poll() must have a float.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
467
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
468 # We always want at least 1 to ensure that select can be called
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
469 # with no file descriptors registered. Otherwise will fail.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
470 max_events = max(len(self._fd_to_key), 1)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
471
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
472 ready = []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
473 fd_events = _syscall_wrapper(self._epoll.poll, True,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
474 timeout=timeout,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
475 maxevents=max_events)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
476 for fd, event_mask in fd_events:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
477 events = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
478 if event_mask & ~select.EPOLLIN:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
479 events |= EVENT_WRITE
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
480 if event_mask & ~select.EPOLLOUT:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
481 events |= EVENT_READ
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
482
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
483 key = self._key_from_fd(fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
484 if key:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
485 ready.append((key, events & key.events))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
486 return ready
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
487
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
488 def close(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
489 self._epoll.close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
490 super(EpollSelector, self).close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
491
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
492 __all__.append('EpollSelector')
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
493
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
494
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
495 if hasattr(select, "devpoll"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
496 class DevpollSelector(BaseSelector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
497 """Solaris /dev/poll selector."""
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
498
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
499 def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
500 super(DevpollSelector, self).__init__()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
501 self._devpoll = select.devpoll()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
502
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
503 def fileno(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
504 return self._devpoll.fileno()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
505
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
506 def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
507 key = super(DevpollSelector, self).register(fileobj, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
508 poll_events = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
509 if events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
510 poll_events |= select.POLLIN
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
511 if events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
512 poll_events |= select.POLLOUT
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
513 self._devpoll.register(key.fd, poll_events)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
514 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
515
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
516 def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
517 key = super(DevpollSelector, self).unregister(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
518 self._devpoll.unregister(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
519 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
520
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
521 def _wrap_poll(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
522 """ Wrapper function for select.poll.poll() so that
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
523 _syscall_wrapper can work with only seconds. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
524 if timeout is not None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
525 if timeout <= 0:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
526 timeout = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
527 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
528 # select.devpoll.poll() has a resolution of 1 millisecond,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
529 # round away from zero to wait *at least* timeout seconds.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
530 timeout = math.ceil(timeout * 1000)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
531
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
532 result = self._devpoll.poll(timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
533 return result
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
534
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
535 def select(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
536 ready = []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
537 fd_events = _syscall_wrapper(self._wrap_poll, True, timeout=timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
538 for fd, event_mask in fd_events:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
539 events = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
540 if event_mask & ~select.POLLIN:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
541 events |= EVENT_WRITE
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
542 if event_mask & ~select.POLLOUT:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
543 events |= EVENT_READ
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
544
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
545 key = self._key_from_fd(fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
546 if key:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
547 ready.append((key, events & key.events))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
548
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
549 return ready
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
550
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
551 def close(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
552 self._devpoll.close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
553 super(DevpollSelector, self).close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
554
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
555 __all__.append('DevpollSelector')
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
556
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
557
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
558 if hasattr(select, "kqueue"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
559 class KqueueSelector(BaseSelector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
560 """ Kqueue / Kevent-based selector """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
561 def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
562 super(KqueueSelector, self).__init__()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
563 self._kqueue = select.kqueue()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
564
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
565 def fileno(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
566 return self._kqueue.fileno()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
567
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
568 def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
569 key = super(KqueueSelector, self).register(fileobj, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
570 if events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
571 kevent = select.kevent(key.fd,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
572 select.KQ_FILTER_READ,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
573 select.KQ_EV_ADD)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
574
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
575 _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
576
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
577 if events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
578 kevent = select.kevent(key.fd,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
579 select.KQ_FILTER_WRITE,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
580 select.KQ_EV_ADD)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
581
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
582 _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
583
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
584 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
585
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
586 def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
587 key = super(KqueueSelector, self).unregister(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
588 if key.events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
589 kevent = select.kevent(key.fd,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
590 select.KQ_FILTER_READ,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
591 select.KQ_EV_DELETE)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
592 try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
593 _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
594 except _ERROR_TYPES:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
595 pass
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
596 if key.events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
597 kevent = select.kevent(key.fd,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
598 select.KQ_FILTER_WRITE,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
599 select.KQ_EV_DELETE)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
600 try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
601 _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
602 except _ERROR_TYPES:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
603 pass
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
604
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
605 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
606
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
607 def select(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
608 if timeout is not None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
609 timeout = max(timeout, 0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
610
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
611 max_events = len(self._fd_to_key) * 2
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
612 ready_fds = {}
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
613
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
614 kevent_list = _syscall_wrapper(self._kqueue.control, True,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
615 None, max_events, timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
616
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
617 for kevent in kevent_list:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
618 fd = kevent.ident
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
619 event_mask = kevent.filter
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
620 events = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
621 if event_mask == select.KQ_FILTER_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
622 events |= EVENT_READ
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
623 if event_mask == select.KQ_FILTER_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
624 events |= EVENT_WRITE
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
625
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
626 key = self._key_from_fd(fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
627 if key:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
628 if key.fd not in ready_fds:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
629 ready_fds[key.fd] = (key, events & key.events)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
630 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
631 old_events = ready_fds[key.fd][1]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
632 ready_fds[key.fd] = (key, (events | old_events) & key.events)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
633
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
634 return list(ready_fds.values())
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
635
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
636 def close(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
637 self._kqueue.close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
638 super(KqueueSelector, self).close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
639
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
640 __all__.append('KqueueSelector')
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
641
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
642
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
643 def _can_allocate(struct):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
644 """ Checks that select structs can be allocated by the underlying
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
645 operating system, not just advertised by the select module. We don't
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
646 check select() because we'll be hopeful that most platforms that
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
647 don't have it available will not advertise it. (ie: GAE) """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
648 try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
649 # select.poll() objects won't fail until used.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
650 if struct == 'poll':
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
651 p = select.poll()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
652 p.poll(0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
653
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
654 # All others will fail on allocation.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
655 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
656 getattr(select, struct)().close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
657 return True
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
658 except (OSError, AttributeError):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
659 return False
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
660
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
661
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
662 # Python 3.5 uses a more direct route to wrap system calls to increase speed.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
663 if sys.version_info >= (3, 5):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
664 def _syscall_wrapper(func, _, *args, **kwargs):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
665 """ This is the short-circuit version of the below logic
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
666 because in Python 3.5+ all selectors restart system calls. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
667 return func(*args, **kwargs)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
668 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
669 def _syscall_wrapper(func, recalc_timeout, *args, **kwargs):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
670 """ Wrapper function for syscalls that could fail due to EINTR.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
671 All functions should be retried if there is time left in the timeout
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
672 in accordance with PEP 475. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
673 timeout = kwargs.get("timeout", None)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
674 if timeout is None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
675 expires = None
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
676 recalc_timeout = False
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
677 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
678 timeout = float(timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
679 if timeout < 0.0: # Timeout less than 0 treated as no timeout.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
680 expires = None
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
681 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
682 expires = monotonic() + timeout
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
683
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
684 args = list(args)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
685 if recalc_timeout and "timeout" not in kwargs:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
686 raise ValueError(
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
687 "Timeout must be in args or kwargs to be recalculated")
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
688
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
689 result = _SYSCALL_SENTINEL
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
690 while result is _SYSCALL_SENTINEL:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
691 try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
692 result = func(*args, **kwargs)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
693 # OSError is thrown by select.select
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
694 # IOError is thrown by select.epoll.poll
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
695 # select.error is thrown by select.poll.poll
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
696 # Aren't we thankful for Python 3.x rework for exceptions?
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
697 except (OSError, IOError, select.error) as e:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
698 # select.error wasn't a subclass of OSError in the past.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
699 errcode = None
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
700 if hasattr(e, "errno"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
701 errcode = e.errno
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
702 elif hasattr(e, "args"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
703 errcode = e.args[0]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
704
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
705 # Also test for the Windows equivalent of EINTR.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
706 is_interrupt = (errcode == errno.EINTR or (hasattr(errno, "WSAEINTR") and
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
707 errcode == errno.WSAEINTR))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
708
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
709 if is_interrupt:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
710 if expires is not None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
711 current_time = monotonic()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
712 if current_time > expires:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
713 raise OSError(errno=errno.ETIMEDOUT)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
714 if recalc_timeout:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
715 if "timeout" in kwargs:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
716 kwargs["timeout"] = expires - current_time
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
717 continue
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
718 raise
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
719 return result
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
720
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
721
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
722 # Choose the best implementation, roughly:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
723 # kqueue == devpoll == epoll > poll > select
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
724 # select() also can't accept a FD > FD_SETSIZE (usually around 1024)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
725 def DefaultSelector():
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
726 """ This function serves as a first call for DefaultSelector to
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
727 detect if the select module is being monkey-patched incorrectly
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
728 by eventlet, greenlet, and preserve proper behavior. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
729 global _DEFAULT_SELECTOR
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
730 if _DEFAULT_SELECTOR is None:
34639
a568a46751b6 selectors2: do not use platform.system()
Jun Wu <quark@fb.com>
parents: 33502
diff changeset
731 if pycompat.isjython:
33502
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
732 _DEFAULT_SELECTOR = JythonSelectSelector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
733 elif _can_allocate('kqueue'):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
734 _DEFAULT_SELECTOR = KqueueSelector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
735 elif _can_allocate('devpoll'):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
736 _DEFAULT_SELECTOR = DevpollSelector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
737 elif _can_allocate('epoll'):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
738 _DEFAULT_SELECTOR = EpollSelector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
739 elif _can_allocate('poll'):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
740 _DEFAULT_SELECTOR = PollSelector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
741 elif hasattr(select, 'select'):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
742 _DEFAULT_SELECTOR = SelectSelector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
743 else: # Platform-specific: AppEngine
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
744 raise RuntimeError('Platform does not have a selector.')
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
745 return _DEFAULT_SELECTOR()