| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 1 | """Event loop and event loop policy.""" | 
|  | 2 |  | 
| Guido van Rossum | 0eaa5ac | 2013-11-04 15:50:46 -0800 | [diff] [blame] | 3 | __all__ = ['AbstractEventLoopPolicy', | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 4 | 'AbstractEventLoop', 'AbstractServer', | 
|  | 5 | 'Handle', 'TimerHandle', | 
|  | 6 | 'get_event_loop_policy', 'set_event_loop_policy', | 
|  | 7 | 'get_event_loop', 'set_event_loop', 'new_event_loop', | 
| Guido van Rossum | 0eaa5ac | 2013-11-04 15:50:46 -0800 | [diff] [blame] | 8 | 'get_child_watcher', 'set_child_watcher', | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 9 | ] | 
|  | 10 |  | 
| Victor Stinner | 307bccc | 2014-06-12 18:39:26 +0200 | [diff] [blame] | 11 | import functools | 
|  | 12 | import inspect | 
| Victor Stinner | 313a980 | 2014-07-29 12:58:23 +0200 | [diff] [blame] | 13 | import reprlib | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 14 | import socket | 
| Victor Stinner | 313a980 | 2014-07-29 12:58:23 +0200 | [diff] [blame] | 15 | import subprocess | 
| Victor Stinner | 307bccc | 2014-06-12 18:39:26 +0200 | [diff] [blame] | 16 | import sys | 
| Victor Stinner | 313a980 | 2014-07-29 12:58:23 +0200 | [diff] [blame] | 17 | import threading | 
|  | 18 | import traceback | 
| Victor Stinner | 307bccc | 2014-06-12 18:39:26 +0200 | [diff] [blame] | 19 |  | 
| Victor Stinner | 71080fc | 2015-07-25 02:23:21 +0200 | [diff] [blame] | 20 | from asyncio import compat | 
| Victor Stinner | 307bccc | 2014-06-12 18:39:26 +0200 | [diff] [blame] | 21 |  | 
| Victor Stinner | 975735f | 2014-06-25 21:41:58 +0200 | [diff] [blame] | 22 |  | 
| Victor Stinner | 307bccc | 2014-06-12 18:39:26 +0200 | [diff] [blame] | 23 | def _get_function_source(func): | 
| Victor Stinner | 71080fc | 2015-07-25 02:23:21 +0200 | [diff] [blame] | 24 | if compat.PY34: | 
| Victor Stinner | 307bccc | 2014-06-12 18:39:26 +0200 | [diff] [blame] | 25 | func = inspect.unwrap(func) | 
|  | 26 | elif hasattr(func, '__wrapped__'): | 
|  | 27 | func = func.__wrapped__ | 
|  | 28 | if inspect.isfunction(func): | 
|  | 29 | code = func.__code__ | 
|  | 30 | return (code.co_filename, code.co_firstlineno) | 
|  | 31 | if isinstance(func, functools.partial): | 
|  | 32 | return _get_function_source(func.func) | 
| Victor Stinner | 71080fc | 2015-07-25 02:23:21 +0200 | [diff] [blame] | 33 | if compat.PY34 and isinstance(func, functools.partialmethod): | 
| Victor Stinner | 307bccc | 2014-06-12 18:39:26 +0200 | [diff] [blame] | 34 | return _get_function_source(func.func) | 
|  | 35 | return None | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 36 |  | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 37 |  | 
| Victor Stinner | 975735f | 2014-06-25 21:41:58 +0200 | [diff] [blame] | 38 | def _format_args(args): | 
| Victor Stinner | 313a980 | 2014-07-29 12:58:23 +0200 | [diff] [blame] | 39 | """Format function arguments. | 
|  | 40 |  | 
|  | 41 | Special case for a single parameter: ('hello',) is formatted as ('hello'). | 
|  | 42 | """ | 
|  | 43 | # use reprlib to limit the length of the output | 
|  | 44 | args_repr = reprlib.repr(args) | 
| Victor Stinner | 975735f | 2014-06-25 21:41:58 +0200 | [diff] [blame] | 45 | if len(args) == 1 and args_repr.endswith(',)'): | 
|  | 46 | args_repr = args_repr[:-2] + ')' | 
|  | 47 | return args_repr | 
|  | 48 |  | 
|  | 49 |  | 
|  | 50 | def _format_callback(func, args, suffix=''): | 
|  | 51 | if isinstance(func, functools.partial): | 
|  | 52 | if args is not None: | 
|  | 53 | suffix = _format_args(args) + suffix | 
|  | 54 | return _format_callback(func.func, func.args, suffix) | 
|  | 55 |  | 
| Guido van Rossum | 0a9933e | 2015-05-02 18:38:24 -0700 | [diff] [blame] | 56 | if hasattr(func, '__qualname__'): | 
|  | 57 | func_repr = getattr(func, '__qualname__') | 
|  | 58 | elif hasattr(func, '__name__'): | 
|  | 59 | func_repr = getattr(func, '__name__') | 
|  | 60 | else: | 
| Victor Stinner | 975735f | 2014-06-25 21:41:58 +0200 | [diff] [blame] | 61 | func_repr = repr(func) | 
|  | 62 |  | 
|  | 63 | if args is not None: | 
|  | 64 | func_repr += _format_args(args) | 
|  | 65 | if suffix: | 
|  | 66 | func_repr += suffix | 
| Guido van Rossum | 0a9933e | 2015-05-02 18:38:24 -0700 | [diff] [blame] | 67 | return func_repr | 
| Victor Stinner | 975735f | 2014-06-25 21:41:58 +0200 | [diff] [blame] | 68 |  | 
| Guido van Rossum | 0a9933e | 2015-05-02 18:38:24 -0700 | [diff] [blame] | 69 | def _format_callback_source(func, args): | 
|  | 70 | func_repr = _format_callback(func, args) | 
| Victor Stinner | 975735f | 2014-06-25 21:41:58 +0200 | [diff] [blame] | 71 | source = _get_function_source(func) | 
|  | 72 | if source: | 
|  | 73 | func_repr += ' at %s:%s' % source | 
|  | 74 | return func_repr | 
|  | 75 |  | 
|  | 76 |  | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 77 | class Handle: | 
|  | 78 | """Object returned by callback registration methods.""" | 
|  | 79 |  | 
| Victor Stinner | 80f53aa | 2014-06-27 13:52:20 +0200 | [diff] [blame] | 80 | __slots__ = ('_callback', '_args', '_cancelled', '_loop', | 
| Victor Stinner | 1b38bc6 | 2014-09-17 23:24:13 +0200 | [diff] [blame] | 81 | '_source_traceback', '_repr', '__weakref__') | 
| Yury Selivanov | b131778 | 2014-02-12 17:01:52 -0500 | [diff] [blame] | 82 |  | 
| Yury Selivanov | 569efa2 | 2014-02-18 18:02:19 -0500 | [diff] [blame] | 83 | def __init__(self, callback, args, loop): | 
| Victor Stinner | dc62b7e | 2014-02-10 00:45:44 +0100 | [diff] [blame] | 84 | assert not isinstance(callback, Handle), 'A Handle is not a callback' | 
| Yury Selivanov | 569efa2 | 2014-02-18 18:02:19 -0500 | [diff] [blame] | 85 | self._loop = loop | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 86 | self._callback = callback | 
|  | 87 | self._args = args | 
|  | 88 | self._cancelled = False | 
| Victor Stinner | 1b38bc6 | 2014-09-17 23:24:13 +0200 | [diff] [blame] | 89 | self._repr = None | 
| Victor Stinner | 80f53aa | 2014-06-27 13:52:20 +0200 | [diff] [blame] | 90 | if self._loop.get_debug(): | 
|  | 91 | self._source_traceback = traceback.extract_stack(sys._getframe(1)) | 
|  | 92 | else: | 
|  | 93 | self._source_traceback = None | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 94 |  | 
| Victor Stinner | 1b38bc6 | 2014-09-17 23:24:13 +0200 | [diff] [blame] | 95 | def _repr_info(self): | 
| Victor Stinner | f68bd88 | 2014-07-10 22:32:58 +0200 | [diff] [blame] | 96 | info = [self.__class__.__name__] | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 97 | if self._cancelled: | 
| Victor Stinner | 975735f | 2014-06-25 21:41:58 +0200 | [diff] [blame] | 98 | info.append('cancelled') | 
| Victor Stinner | f68bd88 | 2014-07-10 22:32:58 +0200 | [diff] [blame] | 99 | if self._callback is not None: | 
| Guido van Rossum | 0a9933e | 2015-05-02 18:38:24 -0700 | [diff] [blame] | 100 | info.append(_format_callback_source(self._callback, self._args)) | 
| Victor Stinner | f68bd88 | 2014-07-10 22:32:58 +0200 | [diff] [blame] | 101 | if self._source_traceback: | 
|  | 102 | frame = self._source_traceback[-1] | 
|  | 103 | info.append('created at %s:%s' % (frame[0], frame[1])) | 
| Victor Stinner | 1b38bc6 | 2014-09-17 23:24:13 +0200 | [diff] [blame] | 104 | return info | 
|  | 105 |  | 
|  | 106 | def __repr__(self): | 
|  | 107 | if self._repr is not None: | 
|  | 108 | return self._repr | 
|  | 109 | info = self._repr_info() | 
| Victor Stinner | f68bd88 | 2014-07-10 22:32:58 +0200 | [diff] [blame] | 110 | return '<%s>' % ' '.join(info) | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 111 |  | 
|  | 112 | def cancel(self): | 
| Yury Selivanov | 592ada9 | 2014-09-25 12:07:56 -0400 | [diff] [blame] | 113 | if not self._cancelled: | 
|  | 114 | self._cancelled = True | 
|  | 115 | if self._loop.get_debug(): | 
|  | 116 | # Keep a representation in debug mode to keep callback and | 
|  | 117 | # parameters. For example, to log the warning | 
|  | 118 | # "Executing <Handle...> took 2.5 second" | 
|  | 119 | self._repr = repr(self) | 
|  | 120 | self._callback = None | 
|  | 121 | self._args = None | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 122 |  | 
|  | 123 | def _run(self): | 
|  | 124 | try: | 
|  | 125 | self._callback(*self._args) | 
| Yury Selivanov | 569efa2 | 2014-02-18 18:02:19 -0500 | [diff] [blame] | 126 | except Exception as exc: | 
| Guido van Rossum | 0a9933e | 2015-05-02 18:38:24 -0700 | [diff] [blame] | 127 | cb = _format_callback_source(self._callback, self._args) | 
| Victor Stinner | 17b53f1 | 2014-06-26 01:35:45 +0200 | [diff] [blame] | 128 | msg = 'Exception in callback {}'.format(cb) | 
| Victor Stinner | 80f53aa | 2014-06-27 13:52:20 +0200 | [diff] [blame] | 129 | context = { | 
| Yury Selivanov | 569efa2 | 2014-02-18 18:02:19 -0500 | [diff] [blame] | 130 | 'message': msg, | 
|  | 131 | 'exception': exc, | 
|  | 132 | 'handle': self, | 
| Victor Stinner | 80f53aa | 2014-06-27 13:52:20 +0200 | [diff] [blame] | 133 | } | 
|  | 134 | if self._source_traceback: | 
|  | 135 | context['source_traceback'] = self._source_traceback | 
|  | 136 | self._loop.call_exception_handler(context) | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 137 | self = None  # Needed to break cycles when an exception occurs. | 
|  | 138 |  | 
|  | 139 |  | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 140 | class TimerHandle(Handle): | 
|  | 141 | """Object returned by timed callback registration methods.""" | 
|  | 142 |  | 
| Yury Selivanov | 592ada9 | 2014-09-25 12:07:56 -0400 | [diff] [blame] | 143 | __slots__ = ['_scheduled', '_when'] | 
| Yury Selivanov | b131778 | 2014-02-12 17:01:52 -0500 | [diff] [blame] | 144 |  | 
| Yury Selivanov | 569efa2 | 2014-02-18 18:02:19 -0500 | [diff] [blame] | 145 | def __init__(self, when, callback, args, loop): | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 146 | assert when is not None | 
| Yury Selivanov | 569efa2 | 2014-02-18 18:02:19 -0500 | [diff] [blame] | 147 | super().__init__(callback, args, loop) | 
| Victor Stinner | 80f53aa | 2014-06-27 13:52:20 +0200 | [diff] [blame] | 148 | if self._source_traceback: | 
|  | 149 | del self._source_traceback[-1] | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 150 | self._when = when | 
| Yury Selivanov | 592ada9 | 2014-09-25 12:07:56 -0400 | [diff] [blame] | 151 | self._scheduled = False | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 152 |  | 
| Victor Stinner | 1b38bc6 | 2014-09-17 23:24:13 +0200 | [diff] [blame] | 153 | def _repr_info(self): | 
|  | 154 | info = super()._repr_info() | 
|  | 155 | pos = 2 if self._cancelled else 1 | 
|  | 156 | info.insert(pos, 'when=%s' % self._when) | 
|  | 157 | return info | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 158 |  | 
|  | 159 | def __hash__(self): | 
|  | 160 | return hash(self._when) | 
|  | 161 |  | 
|  | 162 | def __lt__(self, other): | 
|  | 163 | return self._when < other._when | 
|  | 164 |  | 
|  | 165 | def __le__(self, other): | 
|  | 166 | if self._when < other._when: | 
|  | 167 | return True | 
|  | 168 | return self.__eq__(other) | 
|  | 169 |  | 
|  | 170 | def __gt__(self, other): | 
|  | 171 | return self._when > other._when | 
|  | 172 |  | 
|  | 173 | def __ge__(self, other): | 
|  | 174 | if self._when > other._when: | 
|  | 175 | return True | 
|  | 176 | return self.__eq__(other) | 
|  | 177 |  | 
|  | 178 | def __eq__(self, other): | 
|  | 179 | if isinstance(other, TimerHandle): | 
|  | 180 | return (self._when == other._when and | 
|  | 181 | self._callback == other._callback and | 
|  | 182 | self._args == other._args and | 
|  | 183 | self._cancelled == other._cancelled) | 
|  | 184 | return NotImplemented | 
|  | 185 |  | 
|  | 186 | def __ne__(self, other): | 
|  | 187 | equal = self.__eq__(other) | 
|  | 188 | return NotImplemented if equal is NotImplemented else not equal | 
|  | 189 |  | 
| Yury Selivanov | 592ada9 | 2014-09-25 12:07:56 -0400 | [diff] [blame] | 190 | def cancel(self): | 
|  | 191 | if not self._cancelled: | 
|  | 192 | self._loop._timer_handle_cancelled(self) | 
|  | 193 | super().cancel() | 
|  | 194 |  | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 195 |  | 
|  | 196 | class AbstractServer: | 
| Victor Stinner | cf6f72e | 2013-12-03 18:23:52 +0100 | [diff] [blame] | 197 | """Abstract server returned by create_server().""" | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 198 |  | 
|  | 199 | def close(self): | 
|  | 200 | """Stop serving.  This leaves existing connections open.""" | 
|  | 201 | return NotImplemented | 
|  | 202 |  | 
|  | 203 | def wait_closed(self): | 
|  | 204 | """Coroutine to wait until service is closed.""" | 
|  | 205 | return NotImplemented | 
|  | 206 |  | 
|  | 207 |  | 
|  | 208 | class AbstractEventLoop: | 
|  | 209 | """Abstract event loop.""" | 
|  | 210 |  | 
|  | 211 | # Running and stopping the event loop. | 
|  | 212 |  | 
|  | 213 | def run_forever(self): | 
|  | 214 | """Run the event loop until stop() is called.""" | 
|  | 215 | raise NotImplementedError | 
|  | 216 |  | 
|  | 217 | def run_until_complete(self, future): | 
|  | 218 | """Run the event loop until a Future is done. | 
|  | 219 |  | 
|  | 220 | Return the Future's result, or raise its exception. | 
|  | 221 | """ | 
|  | 222 | raise NotImplementedError | 
|  | 223 |  | 
|  | 224 | def stop(self): | 
|  | 225 | """Stop the event loop as soon as reasonable. | 
|  | 226 |  | 
|  | 227 | Exactly how soon that is may depend on the implementation, but | 
|  | 228 | no more I/O callbacks should be scheduled. | 
|  | 229 | """ | 
|  | 230 | raise NotImplementedError | 
|  | 231 |  | 
|  | 232 | def is_running(self): | 
|  | 233 | """Return whether the event loop is currently running.""" | 
|  | 234 | raise NotImplementedError | 
|  | 235 |  | 
| Victor Stinner | 896a25a | 2014-07-08 11:29:25 +0200 | [diff] [blame] | 236 | def is_closed(self): | 
|  | 237 | """Returns True if the event loop was closed.""" | 
|  | 238 | raise NotImplementedError | 
|  | 239 |  | 
| Guido van Rossum | e3f52ef | 2013-11-01 14:19:04 -0700 | [diff] [blame] | 240 | def close(self): | 
|  | 241 | """Close the loop. | 
|  | 242 |  | 
|  | 243 | The loop should not be running. | 
|  | 244 |  | 
|  | 245 | This is idempotent and irreversible. | 
|  | 246 |  | 
|  | 247 | No other methods should be called after this one. | 
|  | 248 | """ | 
|  | 249 | raise NotImplementedError | 
|  | 250 |  | 
| Yury Selivanov | f6d991d | 2016-09-15 13:10:51 -0400 | [diff] [blame^] | 251 | def shutdown_asyncgens(self): | 
|  | 252 | """Shutdown all active asynchronous generators.""" | 
|  | 253 | raise NotImplementedError | 
|  | 254 |  | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 255 | # Methods scheduling callbacks.  All these return Handles. | 
|  | 256 |  | 
| Yury Selivanov | 592ada9 | 2014-09-25 12:07:56 -0400 | [diff] [blame] | 257 | def _timer_handle_cancelled(self, handle): | 
|  | 258 | """Notification that a TimerHandle has been cancelled.""" | 
|  | 259 | raise NotImplementedError | 
|  | 260 |  | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 261 | def call_soon(self, callback, *args): | 
|  | 262 | return self.call_later(0, callback, *args) | 
|  | 263 |  | 
|  | 264 | def call_later(self, delay, callback, *args): | 
|  | 265 | raise NotImplementedError | 
|  | 266 |  | 
|  | 267 | def call_at(self, when, callback, *args): | 
|  | 268 | raise NotImplementedError | 
|  | 269 |  | 
|  | 270 | def time(self): | 
|  | 271 | raise NotImplementedError | 
|  | 272 |  | 
| Yury Selivanov | 7661db6 | 2016-05-16 15:38:39 -0400 | [diff] [blame] | 273 | def create_future(self): | 
|  | 274 | raise NotImplementedError | 
|  | 275 |  | 
| Victor Stinner | 896a25a | 2014-07-08 11:29:25 +0200 | [diff] [blame] | 276 | # Method scheduling a coroutine object: create a task. | 
|  | 277 |  | 
|  | 278 | def create_task(self, coro): | 
|  | 279 | raise NotImplementedError | 
|  | 280 |  | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 281 | # Methods for interacting with threads. | 
|  | 282 |  | 
|  | 283 | def call_soon_threadsafe(self, callback, *args): | 
|  | 284 | raise NotImplementedError | 
|  | 285 |  | 
| Yury Selivanov | 740169c | 2015-05-11 14:23:38 -0400 | [diff] [blame] | 286 | def run_in_executor(self, executor, func, *args): | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 287 | raise NotImplementedError | 
|  | 288 |  | 
|  | 289 | def set_default_executor(self, executor): | 
|  | 290 | raise NotImplementedError | 
|  | 291 |  | 
|  | 292 | # Network I/O methods returning Futures. | 
|  | 293 |  | 
|  | 294 | def getaddrinfo(self, host, port, *, family=0, type=0, proto=0, flags=0): | 
|  | 295 | raise NotImplementedError | 
|  | 296 |  | 
|  | 297 | def getnameinfo(self, sockaddr, flags=0): | 
|  | 298 | raise NotImplementedError | 
|  | 299 |  | 
|  | 300 | def create_connection(self, protocol_factory, host=None, port=None, *, | 
|  | 301 | ssl=None, family=0, proto=0, flags=0, sock=None, | 
| Guido van Rossum | 21c85a7 | 2013-11-01 14:16:54 -0700 | [diff] [blame] | 302 | local_addr=None, server_hostname=None): | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 303 | raise NotImplementedError | 
|  | 304 |  | 
|  | 305 | def create_server(self, protocol_factory, host=None, port=None, *, | 
|  | 306 | family=socket.AF_UNSPEC, flags=socket.AI_PASSIVE, | 
| Guido van Rossum | b9bf913 | 2015-10-05 09:15:28 -0700 | [diff] [blame] | 307 | sock=None, backlog=100, ssl=None, reuse_address=None, | 
|  | 308 | reuse_port=None): | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 309 | """A coroutine which creates a TCP server bound to host and port. | 
|  | 310 |  | 
|  | 311 | The return value is a Server object which can be used to stop | 
|  | 312 | the service. | 
|  | 313 |  | 
|  | 314 | If host is an empty string or None all interfaces are assumed | 
|  | 315 | and a list of multiple sockets will be returned (most likely | 
| Victor Stinner | 5e4a7d8 | 2015-09-21 18:33:43 +0200 | [diff] [blame] | 316 | one for IPv4 and another one for IPv6). The host parameter can also be a | 
|  | 317 | sequence (e.g. list) of hosts to bind to. | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 318 |  | 
|  | 319 | family can be set to either AF_INET or AF_INET6 to force the | 
|  | 320 | socket to use IPv4 or IPv6. If not set it will be determined | 
|  | 321 | from host (defaults to AF_UNSPEC). | 
|  | 322 |  | 
|  | 323 | flags is a bitmask for getaddrinfo(). | 
|  | 324 |  | 
|  | 325 | sock can optionally be specified in order to use a preexisting | 
|  | 326 | socket object. | 
|  | 327 |  | 
|  | 328 | backlog is the maximum number of queued connections passed to | 
|  | 329 | listen() (defaults to 100). | 
|  | 330 |  | 
|  | 331 | ssl can be set to an SSLContext to enable SSL over the | 
|  | 332 | accepted connections. | 
|  | 333 |  | 
|  | 334 | reuse_address tells the kernel to reuse a local socket in | 
|  | 335 | TIME_WAIT state, without waiting for its natural timeout to | 
|  | 336 | expire. If not specified will automatically be set to True on | 
|  | 337 | UNIX. | 
| Guido van Rossum | b9bf913 | 2015-10-05 09:15:28 -0700 | [diff] [blame] | 338 |  | 
|  | 339 | reuse_port tells the kernel to allow this endpoint to be bound to | 
|  | 340 | the same port as other existing endpoints are bound to, so long as | 
|  | 341 | they all set this flag when being created. This option is not | 
|  | 342 | supported on Windows. | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 343 | """ | 
|  | 344 | raise NotImplementedError | 
|  | 345 |  | 
| Yury Selivanov | b057c52 | 2014-02-18 12:15:06 -0500 | [diff] [blame] | 346 | def create_unix_connection(self, protocol_factory, path, *, | 
|  | 347 | ssl=None, sock=None, | 
|  | 348 | server_hostname=None): | 
|  | 349 | raise NotImplementedError | 
|  | 350 |  | 
|  | 351 | def create_unix_server(self, protocol_factory, path, *, | 
|  | 352 | sock=None, backlog=100, ssl=None): | 
|  | 353 | """A coroutine which creates a UNIX Domain Socket server. | 
|  | 354 |  | 
| Yury Selivanov | dec1a45 | 2014-02-18 22:27:48 -0500 | [diff] [blame] | 355 | The return value is a Server object, which can be used to stop | 
| Yury Selivanov | b057c52 | 2014-02-18 12:15:06 -0500 | [diff] [blame] | 356 | the service. | 
|  | 357 |  | 
|  | 358 | path is a str, representing a file systsem path to bind the | 
|  | 359 | server socket to. | 
|  | 360 |  | 
|  | 361 | sock can optionally be specified in order to use a preexisting | 
|  | 362 | socket object. | 
|  | 363 |  | 
|  | 364 | backlog is the maximum number of queued connections passed to | 
|  | 365 | listen() (defaults to 100). | 
|  | 366 |  | 
|  | 367 | ssl can be set to an SSLContext to enable SSL over the | 
|  | 368 | accepted connections. | 
|  | 369 | """ | 
|  | 370 | raise NotImplementedError | 
|  | 371 |  | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 372 | def create_datagram_endpoint(self, protocol_factory, | 
|  | 373 | local_addr=None, remote_addr=None, *, | 
| Guido van Rossum | b9bf913 | 2015-10-05 09:15:28 -0700 | [diff] [blame] | 374 | family=0, proto=0, flags=0, | 
|  | 375 | reuse_address=None, reuse_port=None, | 
|  | 376 | allow_broadcast=None, sock=None): | 
|  | 377 | """A coroutine which creates a datagram endpoint. | 
|  | 378 |  | 
|  | 379 | This method will try to establish the endpoint in the background. | 
|  | 380 | When successful, the coroutine returns a (transport, protocol) pair. | 
|  | 381 |  | 
|  | 382 | protocol_factory must be a callable returning a protocol instance. | 
|  | 383 |  | 
|  | 384 | socket family AF_INET or socket.AF_INET6 depending on host (or | 
|  | 385 | family if specified), socket type SOCK_DGRAM. | 
|  | 386 |  | 
|  | 387 | reuse_address tells the kernel to reuse a local socket in | 
|  | 388 | TIME_WAIT state, without waiting for its natural timeout to | 
|  | 389 | expire. If not specified it will automatically be set to True on | 
|  | 390 | UNIX. | 
|  | 391 |  | 
|  | 392 | reuse_port tells the kernel to allow this endpoint to be bound to | 
|  | 393 | the same port as other existing endpoints are bound to, so long as | 
|  | 394 | they all set this flag when being created. This option is not | 
|  | 395 | supported on Windows and some UNIX's. If the | 
|  | 396 | :py:data:`~socket.SO_REUSEPORT` constant is not defined then this | 
|  | 397 | capability is unsupported. | 
|  | 398 |  | 
|  | 399 | allow_broadcast tells the kernel to allow this endpoint to send | 
|  | 400 | messages to the broadcast address. | 
|  | 401 |  | 
|  | 402 | sock can optionally be specified in order to use a preexisting | 
|  | 403 | socket object. | 
|  | 404 | """ | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 405 | raise NotImplementedError | 
|  | 406 |  | 
| Guido van Rossum | e3f52ef | 2013-11-01 14:19:04 -0700 | [diff] [blame] | 407 | # Pipes and subprocesses. | 
|  | 408 |  | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 409 | def connect_read_pipe(self, protocol_factory, pipe): | 
| Victor Stinner | a5b257a | 2014-05-29 00:14:03 +0200 | [diff] [blame] | 410 | """Register read pipe in event loop. Set the pipe to non-blocking mode. | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 411 |  | 
|  | 412 | protocol_factory should instantiate object with Protocol interface. | 
| Victor Stinner | a5b257a | 2014-05-29 00:14:03 +0200 | [diff] [blame] | 413 | pipe is a file-like object. | 
|  | 414 | Return pair (transport, protocol), where transport supports the | 
| Guido van Rossum | 9204af4 | 2013-11-30 15:35:42 -0800 | [diff] [blame] | 415 | ReadTransport interface.""" | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 416 | # The reason to accept file-like object instead of just file descriptor | 
|  | 417 | # is: we need to own pipe and close it at transport finishing | 
|  | 418 | # Can got complicated errors if pass f.fileno(), | 
|  | 419 | # close fd in pipe transport then close f and vise versa. | 
|  | 420 | raise NotImplementedError | 
|  | 421 |  | 
|  | 422 | def connect_write_pipe(self, protocol_factory, pipe): | 
| Yury Selivanov | dec1a45 | 2014-02-18 22:27:48 -0500 | [diff] [blame] | 423 | """Register write pipe in event loop. | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 424 |  | 
|  | 425 | protocol_factory should instantiate object with BaseProtocol interface. | 
|  | 426 | Pipe is file-like object already switched to nonblocking. | 
|  | 427 | Return pair (transport, protocol), where transport support | 
| Guido van Rossum | 9204af4 | 2013-11-30 15:35:42 -0800 | [diff] [blame] | 428 | WriteTransport interface.""" | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 429 | # The reason to accept file-like object instead of just file descriptor | 
|  | 430 | # is: we need to own pipe and close it at transport finishing | 
|  | 431 | # Can got complicated errors if pass f.fileno(), | 
|  | 432 | # close fd in pipe transport then close f and vise versa. | 
|  | 433 | raise NotImplementedError | 
|  | 434 |  | 
|  | 435 | def subprocess_shell(self, protocol_factory, cmd, *, stdin=subprocess.PIPE, | 
|  | 436 | stdout=subprocess.PIPE, stderr=subprocess.PIPE, | 
|  | 437 | **kwargs): | 
|  | 438 | raise NotImplementedError | 
|  | 439 |  | 
|  | 440 | def subprocess_exec(self, protocol_factory, *args, stdin=subprocess.PIPE, | 
|  | 441 | stdout=subprocess.PIPE, stderr=subprocess.PIPE, | 
|  | 442 | **kwargs): | 
|  | 443 | raise NotImplementedError | 
|  | 444 |  | 
|  | 445 | # Ready-based callback registration methods. | 
|  | 446 | # The add_*() methods return None. | 
|  | 447 | # The remove_*() methods return True if something was removed, | 
|  | 448 | # False if there was nothing to delete. | 
|  | 449 |  | 
|  | 450 | def add_reader(self, fd, callback, *args): | 
|  | 451 | raise NotImplementedError | 
|  | 452 |  | 
|  | 453 | def remove_reader(self, fd): | 
|  | 454 | raise NotImplementedError | 
|  | 455 |  | 
|  | 456 | def add_writer(self, fd, callback, *args): | 
|  | 457 | raise NotImplementedError | 
|  | 458 |  | 
|  | 459 | def remove_writer(self, fd): | 
|  | 460 | raise NotImplementedError | 
|  | 461 |  | 
|  | 462 | # Completion based I/O methods returning Futures. | 
|  | 463 |  | 
|  | 464 | def sock_recv(self, sock, nbytes): | 
|  | 465 | raise NotImplementedError | 
|  | 466 |  | 
|  | 467 | def sock_sendall(self, sock, data): | 
|  | 468 | raise NotImplementedError | 
|  | 469 |  | 
|  | 470 | def sock_connect(self, sock, address): | 
|  | 471 | raise NotImplementedError | 
|  | 472 |  | 
|  | 473 | def sock_accept(self, sock): | 
|  | 474 | raise NotImplementedError | 
|  | 475 |  | 
|  | 476 | # Signal handling. | 
|  | 477 |  | 
|  | 478 | def add_signal_handler(self, sig, callback, *args): | 
|  | 479 | raise NotImplementedError | 
|  | 480 |  | 
|  | 481 | def remove_signal_handler(self, sig): | 
|  | 482 | raise NotImplementedError | 
|  | 483 |  | 
| Yury Selivanov | 740169c | 2015-05-11 14:23:38 -0400 | [diff] [blame] | 484 | # Task factory. | 
|  | 485 |  | 
|  | 486 | def set_task_factory(self, factory): | 
|  | 487 | raise NotImplementedError | 
|  | 488 |  | 
|  | 489 | def get_task_factory(self): | 
|  | 490 | raise NotImplementedError | 
|  | 491 |  | 
| Yury Selivanov | 569efa2 | 2014-02-18 18:02:19 -0500 | [diff] [blame] | 492 | # Error handlers. | 
|  | 493 |  | 
| Yury Selivanov | 7ed7ce6 | 2016-05-16 15:20:38 -0400 | [diff] [blame] | 494 | def get_exception_handler(self): | 
|  | 495 | raise NotImplementedError | 
|  | 496 |  | 
| Yury Selivanov | 569efa2 | 2014-02-18 18:02:19 -0500 | [diff] [blame] | 497 | def set_exception_handler(self, handler): | 
|  | 498 | raise NotImplementedError | 
|  | 499 |  | 
|  | 500 | def default_exception_handler(self, context): | 
|  | 501 | raise NotImplementedError | 
|  | 502 |  | 
|  | 503 | def call_exception_handler(self, context): | 
|  | 504 | raise NotImplementedError | 
|  | 505 |  | 
| Victor Stinner | 0f3e6bc | 2014-02-19 23:15:02 +0100 | [diff] [blame] | 506 | # Debug flag management. | 
|  | 507 |  | 
|  | 508 | def get_debug(self): | 
|  | 509 | raise NotImplementedError | 
|  | 510 |  | 
|  | 511 | def set_debug(self, enabled): | 
|  | 512 | raise NotImplementedError | 
|  | 513 |  | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 514 |  | 
|  | 515 | class AbstractEventLoopPolicy: | 
|  | 516 | """Abstract policy for accessing the event loop.""" | 
|  | 517 |  | 
|  | 518 | def get_event_loop(self): | 
| Victor Stinner | f9e49dd | 2014-06-05 12:06:44 +0200 | [diff] [blame] | 519 | """Get the event loop for the current context. | 
|  | 520 |  | 
|  | 521 | Returns an event loop object implementing the BaseEventLoop interface, | 
|  | 522 | or raises an exception in case no event loop has been set for the | 
|  | 523 | current context and the current policy does not specify to create one. | 
|  | 524 |  | 
|  | 525 | It should never return None.""" | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 526 | raise NotImplementedError | 
|  | 527 |  | 
|  | 528 | def set_event_loop(self, loop): | 
| Victor Stinner | f9e49dd | 2014-06-05 12:06:44 +0200 | [diff] [blame] | 529 | """Set the event loop for the current context to loop.""" | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 530 | raise NotImplementedError | 
|  | 531 |  | 
|  | 532 | def new_event_loop(self): | 
| Victor Stinner | f9e49dd | 2014-06-05 12:06:44 +0200 | [diff] [blame] | 533 | """Create and return a new event loop object according to this | 
|  | 534 | policy's rules. If there's need to set this loop as the event loop for | 
|  | 535 | the current context, set_event_loop must be called explicitly.""" | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 536 | raise NotImplementedError | 
|  | 537 |  | 
| Guido van Rossum | 0eaa5ac | 2013-11-04 15:50:46 -0800 | [diff] [blame] | 538 | # Child processes handling (Unix only). | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 539 |  | 
| Guido van Rossum | 0eaa5ac | 2013-11-04 15:50:46 -0800 | [diff] [blame] | 540 | def get_child_watcher(self): | 
| Victor Stinner | f9e49dd | 2014-06-05 12:06:44 +0200 | [diff] [blame] | 541 | "Get the watcher for child processes." | 
| Guido van Rossum | 0eaa5ac | 2013-11-04 15:50:46 -0800 | [diff] [blame] | 542 | raise NotImplementedError | 
|  | 543 |  | 
|  | 544 | def set_child_watcher(self, watcher): | 
| Victor Stinner | f9e49dd | 2014-06-05 12:06:44 +0200 | [diff] [blame] | 545 | """Set the watcher for child processes.""" | 
| Guido van Rossum | 0eaa5ac | 2013-11-04 15:50:46 -0800 | [diff] [blame] | 546 | raise NotImplementedError | 
|  | 547 |  | 
|  | 548 |  | 
|  | 549 | class BaseDefaultEventLoopPolicy(AbstractEventLoopPolicy): | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 550 | """Default policy implementation for accessing the event loop. | 
|  | 551 |  | 
|  | 552 | In this policy, each thread has its own event loop.  However, we | 
|  | 553 | only automatically create an event loop by default for the main | 
|  | 554 | thread; other threads by default have no event loop. | 
|  | 555 |  | 
|  | 556 | Other policies may have different rules (e.g. a single global | 
|  | 557 | event loop, or automatically creating an event loop per thread, or | 
|  | 558 | using some other notion of context to which an event loop is | 
|  | 559 | associated). | 
|  | 560 | """ | 
|  | 561 |  | 
| Guido van Rossum | 0eaa5ac | 2013-11-04 15:50:46 -0800 | [diff] [blame] | 562 | _loop_factory = None | 
|  | 563 |  | 
|  | 564 | class _Local(threading.local): | 
|  | 565 | _loop = None | 
|  | 566 | _set_called = False | 
|  | 567 |  | 
|  | 568 | def __init__(self): | 
|  | 569 | self._local = self._Local() | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 570 |  | 
|  | 571 | def get_event_loop(self): | 
|  | 572 | """Get the event loop. | 
|  | 573 |  | 
|  | 574 | This may be None or an instance of EventLoop. | 
|  | 575 | """ | 
| Guido van Rossum | 0eaa5ac | 2013-11-04 15:50:46 -0800 | [diff] [blame] | 576 | if (self._local._loop is None and | 
|  | 577 | not self._local._set_called and | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 578 | isinstance(threading.current_thread(), threading._MainThread)): | 
| Guido van Rossum | cced076 | 2013-11-27 10:37:13 -0800 | [diff] [blame] | 579 | self.set_event_loop(self.new_event_loop()) | 
| Victor Stinner | 3a1c738 | 2014-12-18 01:20:10 +0100 | [diff] [blame] | 580 | if self._local._loop is None: | 
|  | 581 | raise RuntimeError('There is no current event loop in thread %r.' | 
|  | 582 | % threading.current_thread().name) | 
| Guido van Rossum | 0eaa5ac | 2013-11-04 15:50:46 -0800 | [diff] [blame] | 583 | return self._local._loop | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 584 |  | 
|  | 585 | def set_event_loop(self, loop): | 
|  | 586 | """Set the event loop.""" | 
| Guido van Rossum | 0eaa5ac | 2013-11-04 15:50:46 -0800 | [diff] [blame] | 587 | self._local._set_called = True | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 588 | assert loop is None or isinstance(loop, AbstractEventLoop) | 
| Guido van Rossum | 0eaa5ac | 2013-11-04 15:50:46 -0800 | [diff] [blame] | 589 | self._local._loop = loop | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 590 |  | 
|  | 591 | def new_event_loop(self): | 
|  | 592 | """Create a new event loop. | 
|  | 593 |  | 
|  | 594 | You must call set_event_loop() to make this the current event | 
|  | 595 | loop. | 
|  | 596 | """ | 
| Guido van Rossum | 0eaa5ac | 2013-11-04 15:50:46 -0800 | [diff] [blame] | 597 | return self._loop_factory() | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 598 |  | 
|  | 599 |  | 
|  | 600 | # Event loop policy.  The policy itself is always global, even if the | 
|  | 601 | # policy's rules say that there is an event loop per thread (or other | 
|  | 602 | # notion of context).  The default policy is installed by the first | 
|  | 603 | # call to get_event_loop_policy(). | 
|  | 604 | _event_loop_policy = None | 
|  | 605 |  | 
| Guido van Rossum | 0eaa5ac | 2013-11-04 15:50:46 -0800 | [diff] [blame] | 606 | # Lock for protecting the on-the-fly creation of the event loop policy. | 
|  | 607 | _lock = threading.Lock() | 
|  | 608 |  | 
|  | 609 |  | 
|  | 610 | def _init_event_loop_policy(): | 
|  | 611 | global _event_loop_policy | 
|  | 612 | with _lock: | 
|  | 613 | if _event_loop_policy is None:  # pragma: no branch | 
|  | 614 | from . import DefaultEventLoopPolicy | 
|  | 615 | _event_loop_policy = DefaultEventLoopPolicy() | 
|  | 616 |  | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 617 |  | 
|  | 618 | def get_event_loop_policy(): | 
| Victor Stinner | f9e49dd | 2014-06-05 12:06:44 +0200 | [diff] [blame] | 619 | """Get the current event loop policy.""" | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 620 | if _event_loop_policy is None: | 
| Guido van Rossum | 0eaa5ac | 2013-11-04 15:50:46 -0800 | [diff] [blame] | 621 | _init_event_loop_policy() | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 622 | return _event_loop_policy | 
|  | 623 |  | 
|  | 624 |  | 
|  | 625 | def set_event_loop_policy(policy): | 
| Victor Stinner | f9e49dd | 2014-06-05 12:06:44 +0200 | [diff] [blame] | 626 | """Set the current event loop policy. | 
|  | 627 |  | 
|  | 628 | If policy is None, the default policy is restored.""" | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 629 | global _event_loop_policy | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 630 | assert policy is None or isinstance(policy, AbstractEventLoopPolicy) | 
|  | 631 | _event_loop_policy = policy | 
|  | 632 |  | 
|  | 633 |  | 
|  | 634 | def get_event_loop(): | 
| Victor Stinner | f9e49dd | 2014-06-05 12:06:44 +0200 | [diff] [blame] | 635 | """Equivalent to calling get_event_loop_policy().get_event_loop().""" | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 636 | return get_event_loop_policy().get_event_loop() | 
|  | 637 |  | 
|  | 638 |  | 
|  | 639 | def set_event_loop(loop): | 
| Victor Stinner | f9e49dd | 2014-06-05 12:06:44 +0200 | [diff] [blame] | 640 | """Equivalent to calling get_event_loop_policy().set_event_loop(loop).""" | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 641 | get_event_loop_policy().set_event_loop(loop) | 
|  | 642 |  | 
|  | 643 |  | 
|  | 644 | def new_event_loop(): | 
| Victor Stinner | f9e49dd | 2014-06-05 12:06:44 +0200 | [diff] [blame] | 645 | """Equivalent to calling get_event_loop_policy().new_event_loop().""" | 
| Guido van Rossum | 27b7c7e | 2013-10-17 13:40:50 -0700 | [diff] [blame] | 646 | return get_event_loop_policy().new_event_loop() | 
| Guido van Rossum | 0eaa5ac | 2013-11-04 15:50:46 -0800 | [diff] [blame] | 647 |  | 
|  | 648 |  | 
|  | 649 | def get_child_watcher(): | 
| Victor Stinner | f9e49dd | 2014-06-05 12:06:44 +0200 | [diff] [blame] | 650 | """Equivalent to calling get_event_loop_policy().get_child_watcher().""" | 
| Guido van Rossum | 0eaa5ac | 2013-11-04 15:50:46 -0800 | [diff] [blame] | 651 | return get_event_loop_policy().get_child_watcher() | 
|  | 652 |  | 
|  | 653 |  | 
|  | 654 | def set_child_watcher(watcher): | 
| Victor Stinner | f9e49dd | 2014-06-05 12:06:44 +0200 | [diff] [blame] | 655 | """Equivalent to calling | 
|  | 656 | get_event_loop_policy().set_child_watcher(watcher).""" | 
| Guido van Rossum | 0eaa5ac | 2013-11-04 15:50:46 -0800 | [diff] [blame] | 657 | return get_event_loop_policy().set_child_watcher(watcher) |