annotate mercurial/selectors2.py @ 33507:e9672de52a23

debugignore: eliminate inconsistencies with `hg status` (issue5222) Using a matcher for this command allows processing the named file(s) as relative to cwd. It also leverages the icasefs normalization logic the same way the status command does. (However, a false indicator is given for a nonexistent file in some cases, e.g. passing 'foo.REJ' when that file doesn't exist, and the rule is '*.rej'. Maybe the regex itself needs to be case insensitive on these platforms, at least for the debug command.) Finally, the file printed is relative to cwd and uses platform specific slashes, so a few (glob)s were needed in seemingly unrelated tests.
author Matt Harbison <matt_harbison@yahoo.com>
date Sat, 15 Jul 2017 15:23:29 -0400
parents 5d0c0c8d2929
children a568a46751b6
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 platform
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
33 import select
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
34 import socket
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
35 import sys
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
36 import time
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
37
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
38 namedtuple = collections.namedtuple
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
39 Mapping = collections.Mapping
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
40
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
41 try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
42 monotonic = time.monotonic
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
43 except AttributeError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
44 monotonic = time.time
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
45
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
46 __author__ = 'Seth Michael Larson'
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
47 __email__ = 'sethmichaellarson@protonmail.com'
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
48 __version__ = '2.0.0'
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
49 __license__ = 'MIT'
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
50 __url__ = 'https://www.github.com/SethMichaelLarson/selectors2'
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
51
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
52 __all__ = ['EVENT_READ',
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
53 'EVENT_WRITE',
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
54 'SelectorKey',
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
55 'DefaultSelector',
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
56 'BaseSelector']
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
57
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
58 EVENT_READ = (1 << 0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
59 EVENT_WRITE = (1 << 1)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
60 _DEFAULT_SELECTOR = None
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
61 _SYSCALL_SENTINEL = object() # Sentinel in case a system call returns None.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
62 _ERROR_TYPES = (OSError, IOError, socket.error)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
63
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 SelectorKey = namedtuple('SelectorKey', ['fileobj', 'fd', 'events', 'data'])
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
66
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 class _SelectorMapping(Mapping):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
69 """ Mapping of file objects to selector keys """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
70
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
71 def __init__(self, selector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
72 self._selector = selector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
73
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
74 def __len__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
75 return len(self._selector._fd_to_key)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
76
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
77 def __getitem__(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
78 try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
79 fd = self._selector._fileobj_lookup(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
80 return self._selector._fd_to_key[fd]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
81 except KeyError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
82 raise KeyError("{0!r} is not registered.".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
83
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
84 def __iter__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
85 return iter(self._selector._fd_to_key)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
86
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 def _fileobj_to_fd(fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
89 """ Return a file descriptor from a file object. If
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
90 given an integer will simply return that integer back. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
91 if isinstance(fileobj, int):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
92 fd = fileobj
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
93 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
94 try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
95 fd = int(fileobj.fileno())
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
96 except (AttributeError, TypeError, ValueError):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
97 raise ValueError("Invalid file object: {0!r}".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
98 if fd < 0:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
99 raise ValueError("Invalid file descriptor: {0}".format(fd))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
100 return fd
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
101
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 class BaseSelector(object):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
104 """ Abstract Selector class
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
105
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
106 A selector supports registering file objects to be monitored
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
107 for specific I/O events.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
108
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
109 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
110 `fileno()` method. An arbitrary object can be attached to the
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
111 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
112 a callback, etc.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
113
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
114 A selector can use various implementations (select(), poll(), epoll(),
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
115 and kqueue()) depending on the platform. The 'DefaultSelector' class uses
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
116 the most efficient implementation for the current platform.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
117 """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
118 def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
119 # Maps file descriptors to keys.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
120 self._fd_to_key = {}
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
121
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
122 # Read-only mapping returned by get_map()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
123 self._map = _SelectorMapping(self)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
124
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
125 def _fileobj_lookup(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
126 """ Return a file descriptor from a file object.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
127 This wraps _fileobj_to_fd() to do an exhaustive
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
128 search in case the object is invalid but we still
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
129 have it in our map. Used by unregister() so we can
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
130 unregister an object that was previously registered
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
131 even if it is closed. It is also used by _SelectorMapping
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
132 """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
133 try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
134 return _fileobj_to_fd(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
135 except ValueError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
136
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
137 # Search through all our mapped keys.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
138 for key in self._fd_to_key.values():
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
139 if key.fileobj is fileobj:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
140 return key.fd
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
141
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
142 # Raise ValueError after all.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
143 raise
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
144
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
145 def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
146 """ Register a file object for a set of events to monitor. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
147 if (not events) or (events & ~(EVENT_READ | EVENT_WRITE)):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
148 raise ValueError("Invalid events: {0!r}".format(events))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
149
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
150 key = SelectorKey(fileobj, self._fileobj_lookup(fileobj), events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
151
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
152 if key.fd in self._fd_to_key:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
153 raise KeyError("{0!r} (FD {1}) is already registered"
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
154 .format(fileobj, key.fd))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
155
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
156 self._fd_to_key[key.fd] = key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
157 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
158
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
159 def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
160 """ Unregister a file object from being monitored. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
161 try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
162 key = self._fd_to_key.pop(self._fileobj_lookup(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
163 except KeyError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
164 raise KeyError("{0!r} is not registered".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
165
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
166 # 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
167 except socket.error as err:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
168 if err.errno != errno.EBADF:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
169 raise
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
170 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
171 for key in self._fd_to_key.values():
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
172 if key.fileobj is fileobj:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
173 self._fd_to_key.pop(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
174 break
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
175 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
176 raise KeyError("{0!r} is not registered".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
177 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
178
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
179 def modify(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
180 """ Change a registered file object monitored events and data. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
181 # NOTE: Some subclasses optimize this operation even further.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
182 try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
183 key = self._fd_to_key[self._fileobj_lookup(fileobj)]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
184 except KeyError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
185 raise KeyError("{0!r} is not registered".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
186
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
187 if events != key.events:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
188 self.unregister(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
189 key = self.register(fileobj, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
190
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
191 elif data != key.data:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
192 # Use a shortcut to update the data.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
193 key = key._replace(data=data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
194 self._fd_to_key[key.fd] = key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
195
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
196 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
197
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
198 def select(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
199 """ Perform the actual selection until some monitored file objects
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
200 are ready or the timeout expires. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
201 raise NotImplementedError()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
202
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
203 def close(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
204 """ Close the selector. This must be called to ensure that all
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
205 underlying resources are freed. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
206 self._fd_to_key.clear()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
207 self._map = None
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
208
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
209 def get_key(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
210 """ Return the key associated with a registered file object. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
211 mapping = self.get_map()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
212 if mapping is None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
213 raise RuntimeError("Selector is closed")
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
214 try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
215 return mapping[fileobj]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
216 except KeyError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
217 raise KeyError("{0!r} is not registered".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
218
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
219 def get_map(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
220 """ Return a mapping of file objects to selector keys """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
221 return self._map
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
222
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
223 def _key_from_fd(self, fd):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
224 """ Return the key associated to a given file descriptor
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
225 Return None if it is not found. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
226 try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
227 return self._fd_to_key[fd]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
228 except KeyError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
229 return None
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
230
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
231 def __enter__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
232 return self
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
233
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
234 def __exit__(self, *_):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
235 self.close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
236
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 # Almost all platforms have select.select()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
239 if hasattr(select, "select"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
240 class SelectSelector(BaseSelector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
241 """ Select-based selector. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
242 def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
243 super(SelectSelector, self).__init__()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
244 self._readers = set()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
245 self._writers = set()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
246
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
247 def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
248 key = super(SelectSelector, self).register(fileobj, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
249 if events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
250 self._readers.add(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
251 if events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
252 self._writers.add(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
253 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
254
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
255 def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
256 key = super(SelectSelector, self).unregister(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
257 self._readers.discard(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
258 self._writers.discard(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
259 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
260
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
261 def select(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
262 # Selecting on empty lists on Windows errors out.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
263 if not len(self._readers) and not len(self._writers):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
264 return []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
265
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
266 timeout = None if timeout is None else max(timeout, 0.0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
267 ready = []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
268 r, w, _ = _syscall_wrapper(self._wrap_select, True, self._readers,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
269 self._writers, timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
270 r = set(r)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
271 w = set(w)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
272 for fd in r | w:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
273 events = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
274 if fd in r:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
275 events |= EVENT_READ
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
276 if fd in w:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
277 events |= EVENT_WRITE
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
278
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
279 key = self._key_from_fd(fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
280 if key:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
281 ready.append((key, events & key.events))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
282 return ready
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
283
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
284 def _wrap_select(self, r, w, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
285 """ Wrapper for select.select because timeout is a positional arg """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
286 return select.select(r, w, [], timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
287
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
288 __all__.append('SelectSelector')
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
289
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
290 # Jython has a different implementation of .fileno() for socket objects.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
291 if platform.system() == 'Java':
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
292 class _JythonSelectorMapping(object):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
293 """ This is an implementation of _SelectorMapping that is built
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
294 for use specifically with Jython, which does not provide a hashable
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
295 value from socket.socket.fileno(). """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
296
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
297 def __init__(self, selector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
298 assert isinstance(selector, JythonSelectSelector)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
299 self._selector = selector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
300
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
301 def __len__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
302 return len(self._selector._sockets)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
303
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
304 def __getitem__(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
305 for sock, key in self._selector._sockets:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
306 if sock is fileobj:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
307 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
308 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
309 raise KeyError("{0!r} is not registered.".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
310
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
311 class JythonSelectSelector(SelectSelector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
312 """ This is an implementation of SelectSelector that is for Jython
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
313 which works around that Jython's socket.socket.fileno() does not
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
314 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
315 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
316 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
317 directly passing in socket objects rather than registering fds.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
318 See: http://bugs.jython.org/issue1678
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
319 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
320 """
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 def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
323 super(JythonSelectSelector, self).__init__()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
324
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
325 self._sockets = [] # Uses a list of tuples instead of dictionary.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
326 self._map = _JythonSelectorMapping(self)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
327 self._readers = []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
328 self._writers = []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
329
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
330 # Jython has a select.cpython_compatible_select function in older versions.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
331 self._select_func = getattr(select, 'cpython_compatible_select', select.select)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
332
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
333 def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
334 for sock, _ in self._sockets:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
335 if sock is fileobj:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
336 raise KeyError("{0!r} is already registered"
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
337 .format(fileobj, sock))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
338
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
339 key = SelectorKey(fileobj, -1, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
340 self._sockets.append((fileobj, key))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
341
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
342 if events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
343 self._readers.append(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
344 if events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
345 self._writers.append(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
346 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
347
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
348 def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
349 for i, (sock, key) in enumerate(self._sockets):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
350 if sock is fileobj:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
351 break
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
352 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
353 raise KeyError("{0!r} is not registered.".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
354
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
355 if key.events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
356 self._readers.remove(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
357 if key.events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
358 self._writers.remove(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
359
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
360 del self._sockets[i]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
361 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
362
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
363 def _wrap_select(self, r, w, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
364 """ Wrapper for select.select because timeout is a positional arg """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
365 return self._select_func(r, w, [], timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
366
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
367 __all__.append('JythonSelectSelector')
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
368 SelectSelector = JythonSelectSelector # Override so the wrong selector isn't used.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
369
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 if hasattr(select, "poll"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
372 class PollSelector(BaseSelector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
373 """ Poll-based selector """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
374 def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
375 super(PollSelector, self).__init__()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
376 self._poll = select.poll()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
377
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
378 def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
379 key = super(PollSelector, self).register(fileobj, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
380 event_mask = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
381 if events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
382 event_mask |= select.POLLIN
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
383 if events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
384 event_mask |= select.POLLOUT
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
385 self._poll.register(key.fd, event_mask)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
386 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
387
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
388 def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
389 key = super(PollSelector, self).unregister(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
390 self._poll.unregister(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
391 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
392
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
393 def _wrap_poll(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
394 """ Wrapper function for select.poll.poll() so that
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
395 _syscall_wrapper can work with only seconds. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
396 if timeout is not None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
397 if timeout <= 0:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
398 timeout = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
399 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
400 # select.poll.poll() has a resolution of 1 millisecond,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
401 # round away from zero to wait *at least* timeout seconds.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
402 timeout = math.ceil(timeout * 1000)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
403
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
404 result = self._poll.poll(timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
405 return result
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
406
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
407 def select(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
408 ready = []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
409 fd_events = _syscall_wrapper(self._wrap_poll, True, timeout=timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
410 for fd, event_mask in fd_events:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
411 events = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
412 if event_mask & ~select.POLLIN:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
413 events |= EVENT_WRITE
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
414 if event_mask & ~select.POLLOUT:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
415 events |= EVENT_READ
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
416
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
417 key = self._key_from_fd(fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
418 if key:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
419 ready.append((key, events & key.events))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
420
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
421 return ready
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
422
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
423 __all__.append('PollSelector')
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
424
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
425 if hasattr(select, "epoll"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
426 class EpollSelector(BaseSelector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
427 """ Epoll-based selector """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
428 def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
429 super(EpollSelector, self).__init__()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
430 self._epoll = select.epoll()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
431
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
432 def fileno(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
433 return self._epoll.fileno()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
434
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
435 def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
436 key = super(EpollSelector, self).register(fileobj, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
437 events_mask = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
438 if events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
439 events_mask |= select.EPOLLIN
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
440 if events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
441 events_mask |= select.EPOLLOUT
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
442 _syscall_wrapper(self._epoll.register, False, key.fd, events_mask)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
443 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
444
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
445 def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
446 key = super(EpollSelector, self).unregister(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
447 try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
448 _syscall_wrapper(self._epoll.unregister, False, key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
449 except _ERROR_TYPES:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
450 # This can occur when the fd was closed since registry.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
451 pass
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
452 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
453
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
454 def select(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
455 if timeout is not None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
456 if timeout <= 0:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
457 timeout = 0.0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
458 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
459 # select.epoll.poll() has a resolution of 1 millisecond
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
460 # but luckily takes seconds so we don't need a wrapper
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
461 # like PollSelector. Just for better rounding.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
462 timeout = math.ceil(timeout * 1000) * 0.001
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
463 timeout = float(timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
464 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
465 timeout = -1.0 # epoll.poll() must have a float.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
466
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
467 # 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
468 # with no file descriptors registered. Otherwise will fail.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
469 max_events = max(len(self._fd_to_key), 1)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
470
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
471 ready = []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
472 fd_events = _syscall_wrapper(self._epoll.poll, True,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
473 timeout=timeout,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
474 maxevents=max_events)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
475 for fd, event_mask in fd_events:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
476 events = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
477 if event_mask & ~select.EPOLLIN:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
478 events |= EVENT_WRITE
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
479 if event_mask & ~select.EPOLLOUT:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
480 events |= EVENT_READ
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
481
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
482 key = self._key_from_fd(fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
483 if key:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
484 ready.append((key, events & key.events))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
485 return ready
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
486
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
487 def close(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
488 self._epoll.close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
489 super(EpollSelector, self).close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
490
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
491 __all__.append('EpollSelector')
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
492
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 if hasattr(select, "devpoll"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
495 class DevpollSelector(BaseSelector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
496 """Solaris /dev/poll selector."""
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
497
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
498 def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
499 super(DevpollSelector, self).__init__()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
500 self._devpoll = select.devpoll()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
501
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
502 def fileno(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
503 return self._devpoll.fileno()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
504
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
505 def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
506 key = super(DevpollSelector, self).register(fileobj, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
507 poll_events = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
508 if events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
509 poll_events |= select.POLLIN
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
510 if events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
511 poll_events |= select.POLLOUT
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
512 self._devpoll.register(key.fd, poll_events)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
513 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
514
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
515 def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
516 key = super(DevpollSelector, self).unregister(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
517 self._devpoll.unregister(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
518 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
519
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
520 def _wrap_poll(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
521 """ Wrapper function for select.poll.poll() so that
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
522 _syscall_wrapper can work with only seconds. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
523 if timeout is not None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
524 if timeout <= 0:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
525 timeout = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
526 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
527 # select.devpoll.poll() has a resolution of 1 millisecond,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
528 # round away from zero to wait *at least* timeout seconds.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
529 timeout = math.ceil(timeout * 1000)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
530
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
531 result = self._devpoll.poll(timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
532 return result
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
533
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
534 def select(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
535 ready = []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
536 fd_events = _syscall_wrapper(self._wrap_poll, True, timeout=timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
537 for fd, event_mask in fd_events:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
538 events = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
539 if event_mask & ~select.POLLIN:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
540 events |= EVENT_WRITE
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
541 if event_mask & ~select.POLLOUT:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
542 events |= EVENT_READ
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
543
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
544 key = self._key_from_fd(fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
545 if key:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
546 ready.append((key, events & key.events))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
547
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
548 return ready
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
549
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
550 def close(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
551 self._devpoll.close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
552 super(DevpollSelector, self).close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
553
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
554 __all__.append('DevpollSelector')
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
555
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 if hasattr(select, "kqueue"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
558 class KqueueSelector(BaseSelector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
559 """ Kqueue / Kevent-based selector """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
560 def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
561 super(KqueueSelector, self).__init__()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
562 self._kqueue = select.kqueue()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
563
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
564 def fileno(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
565 return self._kqueue.fileno()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
566
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
567 def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
568 key = super(KqueueSelector, self).register(fileobj, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
569 if events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
570 kevent = select.kevent(key.fd,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
571 select.KQ_FILTER_READ,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
572 select.KQ_EV_ADD)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
573
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
574 _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
575
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
576 if events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
577 kevent = select.kevent(key.fd,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
578 select.KQ_FILTER_WRITE,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
579 select.KQ_EV_ADD)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
580
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
581 _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
582
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
583 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
584
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
585 def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
586 key = super(KqueueSelector, self).unregister(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
587 if key.events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
588 kevent = select.kevent(key.fd,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
589 select.KQ_FILTER_READ,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
590 select.KQ_EV_DELETE)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
591 try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
592 _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
593 except _ERROR_TYPES:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
594 pass
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
595 if key.events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
596 kevent = select.kevent(key.fd,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
597 select.KQ_FILTER_WRITE,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
598 select.KQ_EV_DELETE)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
599 try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
600 _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
601 except _ERROR_TYPES:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
602 pass
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
603
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
604 return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
605
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
606 def select(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
607 if timeout is not None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
608 timeout = max(timeout, 0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
609
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
610 max_events = len(self._fd_to_key) * 2
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
611 ready_fds = {}
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
612
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
613 kevent_list = _syscall_wrapper(self._kqueue.control, True,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
614 None, max_events, timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
615
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
616 for kevent in kevent_list:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
617 fd = kevent.ident
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
618 event_mask = kevent.filter
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
619 events = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
620 if event_mask == select.KQ_FILTER_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
621 events |= EVENT_READ
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
622 if event_mask == select.KQ_FILTER_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
623 events |= EVENT_WRITE
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
624
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
625 key = self._key_from_fd(fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
626 if key:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
627 if key.fd not in ready_fds:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
628 ready_fds[key.fd] = (key, events & key.events)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
629 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
630 old_events = ready_fds[key.fd][1]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
631 ready_fds[key.fd] = (key, (events | old_events) & key.events)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
632
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
633 return list(ready_fds.values())
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
634
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
635 def close(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
636 self._kqueue.close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
637 super(KqueueSelector, self).close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
638
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
639 __all__.append('KqueueSelector')
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
640
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 def _can_allocate(struct):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
643 """ Checks that select structs can be allocated by the underlying
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
644 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
645 check select() because we'll be hopeful that most platforms that
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
646 don't have it available will not advertise it. (ie: GAE) """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
647 try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
648 # select.poll() objects won't fail until used.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
649 if struct == 'poll':
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
650 p = select.poll()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
651 p.poll(0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
652
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
653 # All others will fail on allocation.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
654 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
655 getattr(select, struct)().close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
656 return True
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
657 except (OSError, AttributeError):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
658 return False
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
659
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 # 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
662 if sys.version_info >= (3, 5):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
663 def _syscall_wrapper(func, _, *args, **kwargs):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
664 """ This is the short-circuit version of the below logic
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
665 because in Python 3.5+ all selectors restart system calls. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
666 return func(*args, **kwargs)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
667 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
668 def _syscall_wrapper(func, recalc_timeout, *args, **kwargs):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
669 """ Wrapper function for syscalls that could fail due to EINTR.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
670 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
671 in accordance with PEP 475. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
672 timeout = kwargs.get("timeout", None)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
673 if timeout is None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
674 expires = None
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
675 recalc_timeout = False
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
676 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
677 timeout = float(timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
678 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
679 expires = None
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
680 else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
681 expires = monotonic() + timeout
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
682
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
683 args = list(args)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
684 if recalc_timeout and "timeout" not in kwargs:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
685 raise ValueError(
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
686 "Timeout must be in args or kwargs to be recalculated")
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
687
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
688 result = _SYSCALL_SENTINEL
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
689 while result is _SYSCALL_SENTINEL:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
690 try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
691 result = func(*args, **kwargs)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
692 # OSError is thrown by select.select
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
693 # IOError is thrown by select.epoll.poll
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
694 # select.error is thrown by select.poll.poll
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
695 # Aren't we thankful for Python 3.x rework for exceptions?
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
696 except (OSError, IOError, select.error) as e:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
697 # select.error wasn't a subclass of OSError in the past.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
698 errcode = None
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
699 if hasattr(e, "errno"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
700 errcode = e.errno
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
701 elif hasattr(e, "args"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
702 errcode = e.args[0]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
703
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
704 # Also test for the Windows equivalent of EINTR.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
705 is_interrupt = (errcode == errno.EINTR or (hasattr(errno, "WSAEINTR") and
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
706 errcode == errno.WSAEINTR))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
707
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
708 if is_interrupt:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
709 if expires is not None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
710 current_time = monotonic()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
711 if current_time > expires:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
712 raise OSError(errno=errno.ETIMEDOUT)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
713 if recalc_timeout:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
714 if "timeout" in kwargs:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
715 kwargs["timeout"] = expires - current_time
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
716 continue
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
717 raise
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
718 return result
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
719
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 # Choose the best implementation, roughly:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
722 # kqueue == devpoll == epoll > poll > select
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
723 # 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
724 def DefaultSelector():
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
725 """ This function serves as a first call for DefaultSelector to
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
726 detect if the select module is being monkey-patched incorrectly
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
727 by eventlet, greenlet, and preserve proper behavior. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
728 global _DEFAULT_SELECTOR
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
729 if _DEFAULT_SELECTOR is None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
730 if platform.system() == 'Java': # Platform-specific: Jython
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
731 _DEFAULT_SELECTOR = JythonSelectSelector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
732 elif _can_allocate('kqueue'):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
733 _DEFAULT_SELECTOR = KqueueSelector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
734 elif _can_allocate('devpoll'):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
735 _DEFAULT_SELECTOR = DevpollSelector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
736 elif _can_allocate('epoll'):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
737 _DEFAULT_SELECTOR = EpollSelector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
738 elif _can_allocate('poll'):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
739 _DEFAULT_SELECTOR = PollSelector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
740 elif hasattr(select, 'select'):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
741 _DEFAULT_SELECTOR = SelectSelector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
742 else: # Platform-specific: AppEngine
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
743 raise RuntimeError('Platform does not have a selector.')
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
744 return _DEFAULT_SELECTOR()