1# -*- coding: utf-8 -*- 2# Copyright (c) 2018 gevent contributors. See LICENSE for details. 3""" 4Interfaces gevent uses that don't belong any one place. 5 6This is not a public module, these interfaces are not 7currently exposed to the public, they mostly exist for 8documentation and testing purposes. 9 10.. versionadded:: 1.3b2 11 12""" 13from __future__ import absolute_import 14from __future__ import division 15from __future__ import print_function 16 17import sys 18 19from zope.interface import Interface 20from zope.interface import Attribute 21 22_text_type = type(u'') 23 24try: 25 from zope import schema 26except ImportError: # pragma: no cover 27 class _Field(Attribute): 28 __allowed_kw__ = ('readonly', 'min',) 29 def __init__(self, description, required=False, **kwargs): 30 description = u"%s (required? %s)" % (description, required) 31 assert isinstance(description, _text_type) 32 for k in self.__allowed_kw__: 33 kwargs.pop(k, None) 34 if kwargs: 35 raise TypeError("Unexpected keyword arguments: %r" % (kwargs,)) 36 Attribute.__init__(self, description) 37 38 class schema(object): 39 Bool = _Field 40 Float = _Field 41 42 43# pylint:disable=no-method-argument, unused-argument, no-self-argument 44# pylint:disable=inherit-non-class 45 46__all__ = [ 47 'ILoop', 48 'IWatcher', 49 'ICallback', 50] 51 52class ILoop(Interface): 53 """ 54 The common interface expected for all event loops. 55 56 .. caution:: 57 This is an internal, low-level interface. It may change 58 between minor versions of gevent. 59 60 .. rubric:: Watchers 61 62 The methods that create event loop watchers are `io`, `timer`, 63 `signal`, `idle`, `prepare`, `check`, `fork`, `async_`, `child`, 64 `stat`. These all return various types of :class:`IWatcher`. 65 66 All of those methods have one or two common arguments. *ref* is a 67 boolean saying whether the event loop is allowed to exit even if 68 this watcher is still started. *priority* is event loop specific. 69 """ 70 71 default = schema.Bool( 72 description=u"Boolean indicating whether this is the default loop", 73 required=True, 74 readonly=True, 75 ) 76 77 approx_timer_resolution = schema.Float( 78 description=u"Floating point number of seconds giving (approximately) the minimum " 79 "resolution of a timer (and hence the minimun value the sleep can sleep for). " 80 "On libuv, this is fixed by the library, but on libev it is just a guess " 81 "and the actual value is system dependent.", 82 required=True, 83 min=0.0, 84 readonly=True, 85 ) 86 87 def run(nowait=False, once=False): 88 """ 89 Run the event loop. 90 91 This is usually called automatically by the hub greenlet, but 92 in special cases (when the hub is *not* running) you can use 93 this to control how the event loop runs (for example, to integrate 94 it with another event loop). 95 """ 96 97 def now(): 98 """ 99 now() -> float 100 101 Return the loop's notion of the current time. 102 103 This may not necessarily be related to :func:`time.time` (it 104 may have a different starting point), but it must be expressed 105 in fractional seconds (the same *units* used by :func:`time.time`). 106 """ 107 108 def update_now(): 109 """ 110 Update the loop's notion of the current time. 111 112 .. versionadded:: 1.3 113 In the past, this available as ``update``. This is still available as 114 an alias but will be removed in the future. 115 """ 116 117 def destroy(): 118 """ 119 Clean up resources used by this loop. 120 121 If you create loops 122 (especially loops that are not the default) you *should* call 123 this method when you are done with the loop. 124 125 .. caution:: 126 127 As an implementation note, the libev C loop implementation has a 128 finalizer (``__del__``) that destroys the object, but the libuv 129 and libev CFFI implementations do not. The C implementation may change. 130 131 """ 132 133 def io(fd, events, ref=True, priority=None): 134 """ 135 Create and return a new IO watcher for the given *fd*. 136 137 *events* is a bitmask specifying which events to watch 138 for. 1 means read, and 2 means write. 139 """ 140 141 def closing_fd(fd): 142 """ 143 Inform the loop that the file descriptor *fd* is about to be closed. 144 145 The loop may choose to schedule events to be delivered to any active 146 IO watchers for the fd. libev does this so that the active watchers 147 can be closed. 148 149 :return: A boolean value that's true if active IO watchers were 150 queued to run. Closing the FD should be deferred until the next 151 run of the eventloop with a callback. 152 """ 153 154 def timer(after, repeat=0.0, ref=True, priority=None): 155 """ 156 Create and return a timer watcher that will fire after *after* seconds. 157 158 If *repeat* is given, the timer will continue to fire every *repeat* seconds. 159 """ 160 161 def signal(signum, ref=True, priority=None): 162 """ 163 Create and return a signal watcher for the signal *signum*, 164 one of the constants defined in :mod:`signal`. 165 166 This is platform and event loop specific. 167 """ 168 169 def idle(ref=True, priority=None): 170 """ 171 Create and return a watcher that fires when the event loop is idle. 172 """ 173 174 def prepare(ref=True, priority=None): 175 """ 176 Create and return a watcher that fires before the event loop 177 polls for IO. 178 179 .. caution:: This method is not supported by libuv. 180 """ 181 182 def check(ref=True, priority=None): 183 """ 184 Create and return a watcher that fires after the event loop 185 polls for IO. 186 """ 187 188 def fork(ref=True, priority=None): 189 """ 190 Create a watcher that fires when the process forks. 191 192 Availability: Unix. 193 """ 194 195 def async_(ref=True, priority=None): 196 """ 197 Create a watcher that fires when triggered, possibly 198 from another thread. 199 200 .. versionchanged:: 1.3 201 This was previously just named ``async``; for compatibility 202 with Python 3.7 where ``async`` is a keyword it was renamed. 203 On older versions of Python the old name is still around, but 204 it will be removed in the future. 205 """ 206 207 if sys.platform != "win32": 208 209 def child(pid, trace=0, ref=True): 210 """ 211 Create a watcher that fires for events on the child with process ID *pid*. 212 213 This is platform specific and not available on Windows. 214 215 Availability: Unix. 216 """ 217 218 def stat(path, interval=0.0, ref=True, priority=None): 219 """ 220 Create a watcher that monitors the filesystem item at *path*. 221 222 If the operating system doesn't support event notifications 223 from the filesystem, poll for changes every *interval* seconds. 224 """ 225 226 def run_callback(func, *args): 227 """ 228 Run the *func* passing it *args* at the next opportune moment. 229 230 The next opportune moment may be the next iteration of the event loop, 231 the current iteration, or some other time in the future. 232 233 Returns a :class:`ICallback` object. See that documentation for 234 important caveats. 235 236 .. seealso:: :meth:`asyncio.loop.call_soon` 237 The :mod:`asyncio` equivalent. 238 """ 239 240 def run_callback_threadsafe(func, *args): 241 """ 242 Like :meth:`run_callback`, but for use from *outside* the 243 thread that is running this loop. 244 245 This not only schedules the *func* to run, it also causes the 246 loop to notice that the *func* has been scheduled (e.g., it causes 247 the loop to wake up). 248 249 .. versionadded:: 21.1.0 250 251 .. seealso:: :meth:`asyncio.loop.call_soon_threadsafe` 252 The :mod:`asyncio` equivalent. 253 """ 254 255class IWatcher(Interface): 256 """ 257 An event loop watcher. 258 259 These objects call their *callback* function when the event 260 loop detects the event has happened. 261 262 .. important:: You *must* call :meth:`close` when you are 263 done with this object to avoid leaking native resources. 264 """ 265 266 def start(callback, *args, **kwargs): 267 """ 268 Have the event loop begin watching for this event. 269 270 When the event is detected, *callback* will be called with 271 *args*. 272 273 .. caution:: 274 275 Not all watchers accept ``**kwargs``, 276 and some watchers define special meanings for certain keyword args. 277 """ 278 279 def stop(): 280 """ 281 Have the event loop stop watching this event. 282 283 In the future you may call :meth:`start` to begin watching 284 again. 285 """ 286 287 def close(): 288 """ 289 Dispose of any native resources associated with the watcher. 290 291 If we were active, stop. 292 293 Attempting to operate on this object after calling close is 294 undefined. You should dispose of any references you have to it 295 after calling this method. 296 """ 297 298class ICallback(Interface): 299 """ 300 Represents a function that will be run some time in the future. 301 302 Callback functions run in the hub, and as such they cannot use 303 gevent's blocking API; any exception they raise cannot be caught. 304 """ 305 306 pending = schema.Bool(description=u"Has this callback run yet?", 307 readonly=True) 308 309 def stop(): 310 """ 311 If this object is still `pending`, cause it to 312 no longer be `pending`; the function will not be run. 313 """ 314 315 def close(): 316 """ 317 An alias of `stop`. 318 """ 319