corecffi.py 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132
  1. # pylint:disable=too-many-lines, protected-access, redefined-outer-name, not-callable,
  2. # pylint:disable=no-member
  3. from __future__ import absolute_import, print_function
  4. import sys
  5. import os
  6. import traceback
  7. import signal as signalmodule
  8. # pylint:disable=undefined-all-variable
  9. __all__ = [
  10. 'get_version',
  11. 'get_header_version',
  12. 'supported_backends',
  13. 'recommended_backends',
  14. 'embeddable_backends',
  15. 'time',
  16. 'loop',
  17. ]
  18. import gevent.libev._corecffi as _corecffi # pylint:disable=no-name-in-module
  19. ffi = _corecffi.ffi # pylint:disable=no-member
  20. libev = _corecffi.lib # pylint:disable=no-member
  21. if hasattr(libev, 'vfd_open'):
  22. # Must be on windows
  23. assert sys.platform.startswith("win"), "vfd functions only needed on windows"
  24. vfd_open = libev.vfd_open
  25. vfd_free = libev.vfd_free
  26. vfd_get = libev.vfd_get
  27. else:
  28. vfd_open = vfd_free = vfd_get = lambda fd: fd
  29. #####
  30. ## NOTE on Windows:
  31. # The C implementation does several things specially for Windows;
  32. # a possibly incomplete list is:
  33. #
  34. # - the loop runs a periodic signal checker;
  35. # - the io watcher constructor is different and it has a destructor;
  36. # - the child watcher is not defined
  37. #
  38. # The CFFI implementation does none of these things, and so
  39. # is possibly NOT FUNCTIONALLY CORRECT on Win32
  40. #####
  41. #####
  42. ## Note on CFFI objects, callbacks and the lifecycle of watcher objects
  43. #
  44. # Each subclass of `watcher` allocates a C structure of the
  45. # appropriate type e.g., struct gevent_ev_io and holds this pointer in
  46. # its `_gwatcher` attribute. When that watcher instance is garbage
  47. # collected, then the C structure is also freed. The C structure is
  48. # passed to libev from the watcher's start() method and then to the
  49. # appropriate C callback function, e.g., _gevent_ev_io_callback, which
  50. # passes it back to python's _python_callback where we need the
  51. # watcher instance. Therefore, as long as that callback is active (the
  52. # watcher is started), the watcher instance must not be allowed to get
  53. # GC'd---any access at the C level or even the FFI level to the freed
  54. # memory could crash the process.
  55. #
  56. # However, the typical idiom calls for writing something like this:
  57. # loop.io(fd, python_cb).start()
  58. # thus forgetting the newly created watcher subclass and allowing it to be immediately
  59. # GC'd. To combat this, when the watcher is started, it places itself into the loop's
  60. # `_keepaliveset`, and it only removes itself when the watcher's `stop()` method is called.
  61. # Often, this is the *only* reference keeping the watcher object, and hence its C structure,
  62. # alive.
  63. #
  64. # This is slightly complicated by the fact that the python-level
  65. # callback, called from the C callback, could choose to manually stop
  66. # the watcher. When we return to the C level callback, we now have an
  67. # invalid pointer, and attempting to pass it back to Python (e.g., to
  68. # handle an error) could crash. Hence, _python_callback,
  69. # _gevent_io_callback, and _python_handle_error cooperate to make sure
  70. # that the watcher instance stays in the loops `_keepaliveset` while
  71. # the C code could be running---and if it gets removed, to not call back
  72. # to Python again.
  73. # See also https://github.com/gevent/gevent/issues/676
  74. ####
  75. @ffi.callback("int(void* handle, int revents)")
  76. def _python_callback(handle, revents):
  77. """
  78. Returns an integer having one of three values:
  79. - -1
  80. An exception occurred during the callback and you must call
  81. :func:`_python_handle_error` to deal with it. The Python watcher
  82. object will have the exception tuple saved in ``_exc_info``.
  83. - 0
  84. Everything went according to plan. You should check to see if the libev
  85. watcher is still active, and call :func:`_python_stop` if so. This will
  86. clean up the memory.
  87. - 1
  88. Everything went according to plan, but the watcher has already
  89. been stopped. Its memory may no longer be valid.
  90. """
  91. try:
  92. # Even dereferencing the handle needs to be inside the try/except;
  93. # if we don't return normally (e.g., a signal) then we wind up going
  94. # to the 'onerror' handler, which
  95. # is not what we want; that can permanently wedge the loop depending
  96. # on which callback was executing
  97. the_watcher = ffi.from_handle(handle)
  98. args = the_watcher.args
  99. if args is None:
  100. # Legacy behaviour from corecext: convert None into ()
  101. # See test__core_watcher.py
  102. args = _NOARGS
  103. if args and args[0] == GEVENT_CORE_EVENTS:
  104. args = (revents, ) + args[1:]
  105. the_watcher.callback(*args)
  106. except: # pylint:disable=bare-except
  107. the_watcher._exc_info = sys.exc_info()
  108. # Depending on when the exception happened, the watcher
  109. # may or may not have been stopped. We need to make sure its
  110. # memory stays valid so we can stop it at the ev level if needed.
  111. the_watcher.loop._keepaliveset.add(the_watcher)
  112. return -1
  113. else:
  114. if the_watcher in the_watcher.loop._keepaliveset:
  115. # It didn't stop itself
  116. return 0
  117. return 1 # It stopped itself
  118. libev.python_callback = _python_callback
  119. @ffi.callback("void(void* handle, int revents)")
  120. def _python_handle_error(handle, revents):
  121. try:
  122. watcher = ffi.from_handle(handle)
  123. exc_info = watcher._exc_info
  124. del watcher._exc_info
  125. watcher.loop.handle_error(watcher, *exc_info)
  126. finally:
  127. # XXX Since we're here on an error condition, and we
  128. # made sure that the watcher object was put in loop._keepaliveset,
  129. # what about not stopping the watcher? Looks like a possible
  130. # memory leak?
  131. if revents & (libev.EV_READ | libev.EV_WRITE):
  132. try:
  133. watcher.stop()
  134. except: # pylint:disable=bare-except
  135. watcher.loop.handle_error(watcher, *sys.exc_info())
  136. return # pylint:disable=lost-exception
  137. libev.python_handle_error = _python_handle_error
  138. @ffi.callback("void(void* handle)")
  139. def _python_stop(handle):
  140. watcher = ffi.from_handle(handle)
  141. watcher.stop()
  142. libev.python_stop = _python_stop
  143. UNDEF = libev.EV_UNDEF
  144. NONE = libev.EV_NONE
  145. READ = libev.EV_READ
  146. WRITE = libev.EV_WRITE
  147. TIMER = libev.EV_TIMER
  148. PERIODIC = libev.EV_PERIODIC
  149. SIGNAL = libev.EV_SIGNAL
  150. CHILD = libev.EV_CHILD
  151. STAT = libev.EV_STAT
  152. IDLE = libev.EV_IDLE
  153. PREPARE = libev.EV_PREPARE
  154. CHECK = libev.EV_CHECK
  155. EMBED = libev.EV_EMBED
  156. FORK = libev.EV_FORK
  157. CLEANUP = libev.EV_CLEANUP
  158. ASYNC = libev.EV_ASYNC
  159. CUSTOM = libev.EV_CUSTOM
  160. ERROR = libev.EV_ERROR
  161. READWRITE = libev.EV_READ | libev.EV_WRITE
  162. MINPRI = libev.EV_MINPRI
  163. MAXPRI = libev.EV_MAXPRI
  164. BACKEND_PORT = libev.EVBACKEND_PORT
  165. BACKEND_KQUEUE = libev.EVBACKEND_KQUEUE
  166. BACKEND_EPOLL = libev.EVBACKEND_EPOLL
  167. BACKEND_POLL = libev.EVBACKEND_POLL
  168. BACKEND_SELECT = libev.EVBACKEND_SELECT
  169. FORKCHECK = libev.EVFLAG_FORKCHECK
  170. NOINOTIFY = libev.EVFLAG_NOINOTIFY
  171. SIGNALFD = libev.EVFLAG_SIGNALFD
  172. NOSIGMASK = libev.EVFLAG_NOSIGMASK
  173. class _EVENTSType(object):
  174. def __repr__(self):
  175. return 'gevent.core.EVENTS'
  176. EVENTS = GEVENT_CORE_EVENTS = _EVENTSType()
  177. def get_version():
  178. return 'libev-%d.%02d' % (libev.ev_version_major(), libev.ev_version_minor())
  179. def get_header_version():
  180. return 'libev-%d.%02d' % (libev.EV_VERSION_MAJOR, libev.EV_VERSION_MINOR)
  181. _flags = [(libev.EVBACKEND_PORT, 'port'),
  182. (libev.EVBACKEND_KQUEUE, 'kqueue'),
  183. (libev.EVBACKEND_EPOLL, 'epoll'),
  184. (libev.EVBACKEND_POLL, 'poll'),
  185. (libev.EVBACKEND_SELECT, 'select'),
  186. (libev.EVFLAG_NOENV, 'noenv'),
  187. (libev.EVFLAG_FORKCHECK, 'forkcheck'),
  188. (libev.EVFLAG_SIGNALFD, 'signalfd'),
  189. (libev.EVFLAG_NOSIGMASK, 'nosigmask')]
  190. _flags_str2int = dict((string, flag) for (flag, string) in _flags)
  191. _events = [(libev.EV_READ, 'READ'),
  192. (libev.EV_WRITE, 'WRITE'),
  193. (libev.EV__IOFDSET, '_IOFDSET'),
  194. (libev.EV_PERIODIC, 'PERIODIC'),
  195. (libev.EV_SIGNAL, 'SIGNAL'),
  196. (libev.EV_CHILD, 'CHILD'),
  197. (libev.EV_STAT, 'STAT'),
  198. (libev.EV_IDLE, 'IDLE'),
  199. (libev.EV_PREPARE, 'PREPARE'),
  200. (libev.EV_CHECK, 'CHECK'),
  201. (libev.EV_EMBED, 'EMBED'),
  202. (libev.EV_FORK, 'FORK'),
  203. (libev.EV_CLEANUP, 'CLEANUP'),
  204. (libev.EV_ASYNC, 'ASYNC'),
  205. (libev.EV_CUSTOM, 'CUSTOM'),
  206. (libev.EV_ERROR, 'ERROR')]
  207. def _flags_to_list(flags):
  208. result = []
  209. for code, value in _flags:
  210. if flags & code:
  211. result.append(value)
  212. flags &= ~code
  213. if not flags:
  214. break
  215. if flags:
  216. result.append(flags)
  217. return result
  218. if sys.version_info[0] >= 3:
  219. basestring = (bytes, str)
  220. integer_types = (int,)
  221. else:
  222. import __builtin__ # pylint:disable=import-error
  223. basestring = __builtin__.basestring,
  224. integer_types = (int, __builtin__.long)
  225. def _flags_to_int(flags):
  226. # Note, that order does not matter, libev has its own predefined order
  227. if not flags:
  228. return 0
  229. if isinstance(flags, integer_types):
  230. return flags
  231. result = 0
  232. try:
  233. if isinstance(flags, basestring):
  234. flags = flags.split(',')
  235. for value in flags:
  236. value = value.strip().lower()
  237. if value:
  238. result |= _flags_str2int[value]
  239. except KeyError as ex:
  240. raise ValueError('Invalid backend or flag: %s\nPossible values: %s' % (ex, ', '.join(sorted(_flags_str2int.keys()))))
  241. return result
  242. def _str_hex(flag):
  243. if isinstance(flag, integer_types):
  244. return hex(flag)
  245. return str(flag)
  246. def _check_flags(flags):
  247. as_list = []
  248. flags &= libev.EVBACKEND_MASK
  249. if not flags:
  250. return
  251. if not flags & libev.EVBACKEND_ALL:
  252. raise ValueError('Invalid value for backend: 0x%x' % flags)
  253. if not flags & libev.ev_supported_backends():
  254. as_list = [_str_hex(x) for x in _flags_to_list(flags)]
  255. raise ValueError('Unsupported backend: %s' % '|'.join(as_list))
  256. def _events_to_str(events):
  257. result = []
  258. for (flag, string) in _events:
  259. c_flag = flag
  260. if events & c_flag:
  261. result.append(string)
  262. events = events & (~c_flag)
  263. if not events:
  264. break
  265. if events:
  266. result.append(hex(events))
  267. return '|'.join(result)
  268. def supported_backends():
  269. return _flags_to_list(libev.ev_supported_backends())
  270. def recommended_backends():
  271. return _flags_to_list(libev.ev_recommended_backends())
  272. def embeddable_backends():
  273. return _flags_to_list(libev.ev_embeddable_backends())
  274. def time():
  275. return libev.ev_time()
  276. _default_loop_destroyed = False
  277. def _loop_callback(*args, **kwargs):
  278. return ffi.callback(*args, **kwargs)
  279. class loop(object):
  280. # pylint:disable=too-many-public-methods
  281. error_handler = None
  282. def __init__(self, flags=None, default=None):
  283. self._in_callback = False
  284. self._callbacks = []
  285. # self._check is a watcher that runs in each iteration of the
  286. # mainloop, just after the blocking call
  287. self._check = ffi.new("struct ev_check *")
  288. self._check_callback_ffi = _loop_callback("void(*)(struct ev_loop *, void*, int)",
  289. self._check_callback,
  290. onerror=self._check_callback_handle_error)
  291. libev.ev_check_init(self._check, self._check_callback_ffi)
  292. # self._prepare is a watcher that runs in each iteration of the mainloop,
  293. # just before the blocking call
  294. self._prepare = ffi.new("struct ev_prepare *")
  295. self._prepare_callback_ffi = _loop_callback("void(*)(struct ev_loop *, void*, int)",
  296. self._run_callbacks,
  297. onerror=self._check_callback_handle_error)
  298. libev.ev_prepare_init(self._prepare, self._prepare_callback_ffi)
  299. # A timer we start and stop on demand. If we have callbacks,
  300. # too many to run in one iteration of _run_callbacks, we turn this
  301. # on so as to have the next iteration of the run loop return to us
  302. # as quickly as possible.
  303. # TODO: There may be a more efficient way to do this using ev_timer_again;
  304. # see the "ev_timer" section of the ev manpage (http://linux.die.net/man/3/ev)
  305. self._timer0 = ffi.new("struct ev_timer *")
  306. libev.ev_timer_init(self._timer0, libev.gevent_noop, 0.0, 0.0)
  307. # TODO: We may be able to do something nicer and use the existing python_callback
  308. # combined with onerror and the class check/timer/prepare to simplify things
  309. # and unify our handling
  310. c_flags = _flags_to_int(flags)
  311. _check_flags(c_flags)
  312. c_flags |= libev.EVFLAG_NOENV
  313. c_flags |= libev.EVFLAG_FORKCHECK
  314. if default is None:
  315. default = True
  316. if _default_loop_destroyed:
  317. default = False
  318. if default:
  319. self._ptr = libev.gevent_ev_default_loop(c_flags)
  320. if not self._ptr:
  321. raise SystemError("ev_default_loop(%s) failed" % (c_flags, ))
  322. else:
  323. self._ptr = libev.ev_loop_new(c_flags)
  324. if not self._ptr:
  325. raise SystemError("ev_loop_new(%s) failed" % (c_flags, ))
  326. if default or globals()["__SYSERR_CALLBACK"] is None:
  327. set_syserr_cb(self._handle_syserr)
  328. libev.ev_prepare_start(self._ptr, self._prepare)
  329. self.unref()
  330. libev.ev_check_start(self._ptr, self._check)
  331. self.unref()
  332. self._keepaliveset = set()
  333. def _check_callback_handle_error(self, t, v, tb):
  334. # None as the context argument causes the exception to be raised
  335. # in the main greenlet.
  336. self.handle_error(None, t, v, tb)
  337. def _check_callback(self, *args):
  338. # If we have the onerror callback, this is a no-op; all the real
  339. # work to rethrow the exception is done by the onerror callback
  340. pass
  341. def _run_callbacks(self, _evloop, _, _revents):
  342. count = 1000
  343. libev.ev_timer_stop(self._ptr, self._timer0)
  344. while self._callbacks and count > 0:
  345. callbacks = self._callbacks
  346. self._callbacks = []
  347. for cb in callbacks:
  348. self.unref()
  349. callback = cb.callback
  350. args = cb.args
  351. if callback is None or args is None:
  352. # it's been stopped
  353. continue
  354. cb.callback = None
  355. try:
  356. callback(*args)
  357. except: # pylint:disable=bare-except
  358. # If we allow an exception to escape this method (while we are running the ev callback),
  359. # then CFFI will print the error and libev will continue executing.
  360. # There are two problems with this. The first is that the code after
  361. # the loop won't run. The second is that any remaining callbacks scheduled
  362. # for this loop iteration will be silently dropped; they won't run, but they'll
  363. # also not be *stopped* (which is not a huge deal unless you're looking for
  364. # consistency or checking the boolean/pending status; the loop doesn't keep
  365. # a reference to them like it does to watchers...*UNLESS* the callback itself had
  366. # a reference to a watcher; then I don't know what would happen, it depends on
  367. # the state of the watcher---a leak or crash is not totally inconceivable).
  368. # The Cython implementation in core.ppyx uses gevent_call from callbacks.c
  369. # to run the callback, which uses gevent_handle_error to handle any errors the
  370. # Python callback raises...it unconditionally simply prints any error raised
  371. # by loop.handle_error and clears it, so callback handling continues.
  372. # We take a similar approach (but are extra careful about printing)
  373. try:
  374. self.handle_error(cb, *sys.exc_info())
  375. except: # pylint:disable=bare-except
  376. try:
  377. print("Exception while handling another error", file=sys.stderr)
  378. traceback.print_exc()
  379. except: # pylint:disable=bare-except
  380. pass # Nothing we can do here
  381. finally:
  382. # NOTE: this must be reset here, because cb.args is used as a flag in
  383. # the callback class so that bool(cb) of a callback that has been run
  384. # becomes False
  385. cb.args = None
  386. count -= 1
  387. if self._callbacks:
  388. libev.ev_timer_start(self._ptr, self._timer0)
  389. def _stop_aux_watchers(self):
  390. if libev.ev_is_active(self._prepare):
  391. self.ref()
  392. libev.ev_prepare_stop(self._ptr, self._prepare)
  393. if libev.ev_is_active(self._check):
  394. self.ref()
  395. libev.ev_check_stop(self._ptr, self._check)
  396. def destroy(self):
  397. global _default_loop_destroyed
  398. if self._ptr:
  399. self._stop_aux_watchers()
  400. if globals()["__SYSERR_CALLBACK"] == self._handle_syserr:
  401. set_syserr_cb(None)
  402. if libev.ev_is_default_loop(self._ptr):
  403. _default_loop_destroyed = True
  404. libev.ev_loop_destroy(self._ptr)
  405. self._ptr = ffi.NULL
  406. @property
  407. def ptr(self):
  408. return self._ptr
  409. @property
  410. def WatcherType(self):
  411. return watcher
  412. @property
  413. def MAXPRI(self):
  414. return libev.EV_MAXPRI
  415. @property
  416. def MINPRI(self):
  417. return libev.EV_MINPRI
  418. def _handle_syserr(self, message, errno):
  419. try:
  420. errno = os.strerror(errno)
  421. except: # pylint:disable=bare-except
  422. traceback.print_exc()
  423. try:
  424. message = '%s: %s' % (message, errno)
  425. except: # pylint:disable=bare-except
  426. traceback.print_exc()
  427. self.handle_error(None, SystemError, SystemError(message), None)
  428. def handle_error(self, context, type, value, tb):
  429. handle_error = None
  430. error_handler = self.error_handler
  431. if error_handler is not None:
  432. # we do want to do getattr every time so that setting Hub.handle_error property just works
  433. handle_error = getattr(error_handler, 'handle_error', error_handler)
  434. handle_error(context, type, value, tb)
  435. else:
  436. self._default_handle_error(context, type, value, tb)
  437. def _default_handle_error(self, context, type, value, tb): # pylint:disable=unused-argument
  438. # note: Hub sets its own error handler so this is not used by gevent
  439. # this is here to make core.loop usable without the rest of gevent
  440. traceback.print_exception(type, value, tb)
  441. libev.ev_break(self._ptr, libev.EVBREAK_ONE)
  442. def run(self, nowait=False, once=False):
  443. flags = 0
  444. if nowait:
  445. flags |= libev.EVRUN_NOWAIT
  446. if once:
  447. flags |= libev.EVRUN_ONCE
  448. libev.ev_run(self._ptr, flags)
  449. def reinit(self):
  450. libev.ev_loop_fork(self._ptr)
  451. def ref(self):
  452. libev.ev_ref(self._ptr)
  453. def unref(self):
  454. libev.ev_unref(self._ptr)
  455. def break_(self, how=libev.EVBREAK_ONE):
  456. libev.ev_break(self._ptr, how)
  457. def verify(self):
  458. libev.ev_verify(self._ptr)
  459. def now(self):
  460. return libev.ev_now(self._ptr)
  461. def update(self):
  462. libev.ev_now_update(self._ptr)
  463. def __repr__(self):
  464. return '<%s at 0x%x %s>' % (self.__class__.__name__, id(self), self._format())
  465. @property
  466. def default(self):
  467. return True if libev.ev_is_default_loop(self._ptr) else False
  468. @property
  469. def iteration(self):
  470. return libev.ev_iteration(self._ptr)
  471. @property
  472. def depth(self):
  473. return libev.ev_depth(self._ptr)
  474. @property
  475. def backend_int(self):
  476. return libev.ev_backend(self._ptr)
  477. @property
  478. def backend(self):
  479. backend = libev.ev_backend(self._ptr)
  480. for key, value in _flags:
  481. if key == backend:
  482. return value
  483. return backend
  484. @property
  485. def pendingcnt(self):
  486. return libev.ev_pending_count(self._ptr)
  487. def io(self, fd, events, ref=True, priority=None):
  488. return io(self, fd, events, ref, priority)
  489. def timer(self, after, repeat=0.0, ref=True, priority=None):
  490. return timer(self, after, repeat, ref, priority)
  491. def signal(self, signum, ref=True, priority=None):
  492. return signal(self, signum, ref, priority)
  493. def idle(self, ref=True, priority=None):
  494. return idle(self, ref, priority)
  495. def prepare(self, ref=True, priority=None):
  496. return prepare(self, ref, priority)
  497. def check(self, ref=True, priority=None):
  498. return check(self, ref, priority)
  499. def fork(self, ref=True, priority=None):
  500. return fork(self, ref, priority)
  501. def async(self, ref=True, priority=None):
  502. return async(self, ref, priority)
  503. if sys.platform != "win32":
  504. def child(self, pid, trace=0, ref=True):
  505. return child(self, pid, trace, ref)
  506. def install_sigchld(self):
  507. libev.gevent_install_sigchld_handler()
  508. def reset_sigchld(self):
  509. libev.gevent_reset_sigchld_handler()
  510. def stat(self, path, interval=0.0, ref=True, priority=None):
  511. return stat(self, path, interval, ref, priority)
  512. def callback(self, priority=None):
  513. return callback(self, priority)
  514. def run_callback(self, func, *args):
  515. cb = callback(func, args)
  516. self._callbacks.append(cb)
  517. self.ref()
  518. return cb
  519. def _format(self):
  520. if not self._ptr:
  521. return 'destroyed'
  522. msg = self.backend
  523. if self.default:
  524. msg += ' default'
  525. msg += ' pending=%s' % self.pendingcnt
  526. msg += self._format_details()
  527. return msg
  528. def _format_details(self):
  529. msg = ''
  530. fileno = self.fileno()
  531. try:
  532. activecnt = self.activecnt
  533. except AttributeError:
  534. activecnt = None
  535. if activecnt is not None:
  536. msg += ' ref=' + repr(activecnt)
  537. if fileno is not None:
  538. msg += ' fileno=' + repr(fileno)
  539. #if sigfd is not None and sigfd != -1:
  540. # msg += ' sigfd=' + repr(sigfd)
  541. return msg
  542. def fileno(self):
  543. if self._ptr:
  544. fd = self._ptr.backend_fd
  545. if fd >= 0:
  546. return fd
  547. @property
  548. def activecnt(self):
  549. if not self._ptr:
  550. raise ValueError('operation on destroyed loop')
  551. return self._ptr.activecnt
  552. # For times when *args is captured but often not passed (empty),
  553. # we can avoid keeping the new tuple that was created for *args
  554. # around by using a constant.
  555. _NOARGS = ()
  556. class callback(object):
  557. __slots__ = ('callback', 'args')
  558. def __init__(self, callback, args):
  559. self.callback = callback
  560. self.args = args or _NOARGS
  561. def stop(self):
  562. self.callback = None
  563. self.args = None
  564. # Note that __nonzero__ and pending are different
  565. # bool() is used in contexts where we need to know whether to schedule another callback,
  566. # so it's true if it's pending or currently running
  567. # 'pending' has the same meaning as libev watchers: it is cleared before actually
  568. # running the callback
  569. def __nonzero__(self):
  570. # it's nonzero if it's pending or currently executing
  571. # NOTE: This depends on loop._run_callbacks setting the args property
  572. # to None.
  573. return self.args is not None
  574. __bool__ = __nonzero__
  575. @property
  576. def pending(self):
  577. return self.callback is not None
  578. def _format(self):
  579. return ''
  580. def __repr__(self):
  581. result = "<%s at 0x%x" % (self.__class__.__name__, id(self))
  582. if self.pending:
  583. result += " pending"
  584. if self.callback is not None:
  585. result += " callback=%r" % (self.callback, )
  586. if self.args is not None:
  587. result += " args=%r" % (self.args, )
  588. if self.callback is None and self.args is None:
  589. result += " stopped"
  590. return result + ">"
  591. class watcher(object):
  592. def __init__(self, _loop, ref=True, priority=None, args=_NOARGS):
  593. self.loop = _loop
  594. if ref:
  595. self._flags = 0
  596. else:
  597. self._flags = 4
  598. self._args = None
  599. self._callback = None
  600. self._handle = ffi.new_handle(self)
  601. self._watcher = ffi.new(self._watcher_struct_pointer_type)
  602. self._watcher.data = self._handle
  603. if priority is not None:
  604. libev.ev_set_priority(self._watcher, priority)
  605. self._watcher_init(self._watcher,
  606. self._watcher_callback,
  607. *args)
  608. # A string identifying the type of libev object we watch, e.g., 'ev_io'
  609. # This should be a class attribute.
  610. _watcher_type = None
  611. # A class attribute that is the callback on the libev object that init's the C struct,
  612. # e.g., libev.ev_io_init. If None, will be set by _init_subclasses.
  613. _watcher_init = None
  614. # A class attribute that is the callback on the libev object that starts the C watcher,
  615. # e.g., libev.ev_io_start. If None, will be set by _init_subclasses.
  616. _watcher_start = None
  617. # A class attribute that is the callback on the libev object that stops the C watcher,
  618. # e.g., libev.ev_io_stop. If None, will be set by _init_subclasses.
  619. _watcher_stop = None
  620. # A cffi ctype object identifying the struct pointer we create.
  621. # This is a class attribute set based on the _watcher_type
  622. _watcher_struct_pointer_type = None
  623. # The attribute of the libev object identifying the custom
  624. # callback function for this type of watcher. This is a class
  625. # attribute set based on the _watcher_type in _init_subclasses.
  626. _watcher_callback = None
  627. @classmethod
  628. def _init_subclasses(cls):
  629. for subclass in cls.__subclasses__(): # pylint:disable=no-member
  630. watcher_type = subclass._watcher_type
  631. subclass._watcher_struct_pointer_type = ffi.typeof('struct ' + watcher_type + '*')
  632. subclass._watcher_callback = ffi.addressof(libev,
  633. '_gevent_generic_callback')
  634. for name in 'start', 'stop', 'init':
  635. ev_name = watcher_type + '_' + name
  636. watcher_name = '_watcher' + '_' + name
  637. if getattr(subclass, watcher_name) is None:
  638. setattr(subclass, watcher_name,
  639. getattr(libev, ev_name))
  640. # this is not needed, since we keep alive the watcher while it's started
  641. #def __del__(self):
  642. # self._watcher_stop(self.loop._ptr, self._watcher)
  643. def __repr__(self):
  644. formats = self._format()
  645. result = "<%s at 0x%x%s" % (self.__class__.__name__, id(self), formats)
  646. if self.pending:
  647. result += " pending"
  648. if self.callback is not None:
  649. result += " callback=%r" % (self.callback, )
  650. if self.args is not None:
  651. result += " args=%r" % (self.args, )
  652. if self.callback is None and self.args is None:
  653. result += " stopped"
  654. result += " handle=%s" % (self._watcher.data)
  655. return result + ">"
  656. def _format(self):
  657. return ''
  658. def _libev_unref(self):
  659. if self._flags & 6 == 4:
  660. self.loop.unref()
  661. self._flags |= 2
  662. def _get_ref(self):
  663. return False if self._flags & 4 else True
  664. def _set_ref(self, value):
  665. if value:
  666. if not self._flags & 4:
  667. return # ref is already True
  668. if self._flags & 2: # ev_unref was called, undo
  669. self.loop.ref()
  670. self._flags &= ~6 # do not want unref, no outstanding unref
  671. else:
  672. if self._flags & 4:
  673. return # ref is already False
  674. self._flags |= 4
  675. if not self._flags & 2 and libev.ev_is_active(self._watcher):
  676. self.loop.unref()
  677. self._flags |= 2
  678. ref = property(_get_ref, _set_ref)
  679. def _get_callback(self):
  680. return self._callback
  681. def _set_callback(self, cb):
  682. if not callable(cb) and cb is not None:
  683. raise TypeError("Expected callable, not %r" % (cb, ))
  684. self._callback = cb
  685. callback = property(_get_callback, _set_callback)
  686. def _get_args(self):
  687. return self._args
  688. def _set_args(self, args):
  689. if not isinstance(args, tuple) and args is not None:
  690. raise TypeError("args must be a tuple or None")
  691. self._args = args
  692. args = property(_get_args, _set_args)
  693. def start(self, callback, *args):
  694. if callback is None:
  695. raise TypeError('callback must be callable, not None')
  696. self.callback = callback
  697. self.args = args or _NOARGS
  698. self._libev_unref()
  699. self.loop._keepaliveset.add(self)
  700. self._watcher_start(self.loop._ptr, self._watcher)
  701. def stop(self):
  702. if self._flags & 2:
  703. self.loop.ref()
  704. self._flags &= ~2
  705. self._watcher_stop(self.loop._ptr, self._watcher)
  706. self.loop._keepaliveset.discard(self)
  707. self._callback = None
  708. self.args = None
  709. def _get_priority(self):
  710. return libev.ev_priority(self._watcher)
  711. def _set_priority(self, priority):
  712. if libev.ev_is_active(self._watcher):
  713. raise AttributeError("Cannot set priority of an active watcher")
  714. libev.ev_set_priority(self._watcher, priority)
  715. priority = property(_get_priority, _set_priority)
  716. def feed(self, revents, callback, *args):
  717. self.callback = callback
  718. self.args = args or _NOARGS
  719. if self._flags & 6 == 4:
  720. self.loop.unref()
  721. self._flags |= 2
  722. libev.ev_feed_event(self.loop._ptr, self._watcher, revents)
  723. if not self._flags & 1:
  724. # Py_INCREF(<PyObjectPtr>self)
  725. self._flags |= 1
  726. @property
  727. def active(self):
  728. return True if libev.ev_is_active(self._watcher) else False
  729. @property
  730. def pending(self):
  731. return True if libev.ev_is_pending(self._watcher) else False
  732. class io(watcher):
  733. _watcher_type = 'ev_io'
  734. def __init__(self, loop, fd, events, ref=True, priority=None):
  735. # XXX: Win32: Need to vfd_open the fd and free the old one?
  736. # XXX: Win32: Need a destructor to free the old fd?
  737. if fd < 0:
  738. raise ValueError('fd must be non-negative: %r' % fd)
  739. if events & ~(libev.EV__IOFDSET | libev.EV_READ | libev.EV_WRITE):
  740. raise ValueError('illegal event mask: %r' % events)
  741. watcher.__init__(self, loop, ref=ref, priority=priority, args=(fd, events))
  742. def start(self, callback, *args, **kwargs):
  743. # pylint:disable=arguments-differ
  744. args = args or _NOARGS
  745. if kwargs.get('pass_events'):
  746. args = (GEVENT_CORE_EVENTS, ) + args
  747. watcher.start(self, callback, *args)
  748. def _get_fd(self):
  749. return vfd_get(self._watcher.fd)
  750. def _set_fd(self, fd):
  751. if libev.ev_is_active(self._watcher):
  752. raise AttributeError("'io' watcher attribute 'fd' is read-only while watcher is active")
  753. vfd = vfd_open(fd)
  754. vfd_free(self._watcher.fd)
  755. self._watcher_init(self._watcher, self._watcher_callback, vfd, self._watcher.events)
  756. fd = property(_get_fd, _set_fd)
  757. def _get_events(self):
  758. return self._watcher.events
  759. def _set_events(self, events):
  760. if libev.ev_is_active(self._watcher):
  761. raise AttributeError("'io' watcher attribute 'events' is read-only while watcher is active")
  762. self._watcher_init(self._watcher, self._watcher_callback, self._watcher.fd, events)
  763. events = property(_get_events, _set_events)
  764. @property
  765. def events_str(self):
  766. return _events_to_str(self._watcher.events)
  767. def _format(self):
  768. return ' fd=%s events=%s' % (self.fd, self.events_str)
  769. class timer(watcher):
  770. _watcher_type = 'ev_timer'
  771. def __init__(self, loop, after=0.0, repeat=0.0, ref=True, priority=None):
  772. if repeat < 0.0:
  773. raise ValueError("repeat must be positive or zero: %r" % repeat)
  774. watcher.__init__(self, loop, ref=ref, priority=priority, args=(after, repeat))
  775. def start(self, callback, *args, **kw):
  776. # pylint:disable=arguments-differ
  777. update = kw.get("update", True)
  778. if update:
  779. # Quoth the libev doc: "This is a costly operation and is
  780. # usually done automatically within ev_run(). This
  781. # function is rarely useful, but when some event callback
  782. # runs for a very long time without entering the event
  783. # loop, updating libev's idea of the current time is a
  784. # good idea."
  785. # So do we really need to default to true?
  786. libev.ev_now_update(self.loop._ptr)
  787. watcher.start(self, callback, *args)
  788. @property
  789. def at(self):
  790. return self._watcher.at
  791. def again(self, callback, *args, **kw):
  792. # Exactly the same as start(), just with a different initializer
  793. # function
  794. self._watcher_start = libev.ev_timer_again
  795. try:
  796. self.start(callback, *args, **kw)
  797. finally:
  798. del self._watcher_start
  799. class signal(watcher):
  800. _watcher_type = 'ev_signal'
  801. def __init__(self, loop, signalnum, ref=True, priority=None):
  802. if signalnum < 1 or signalnum >= signalmodule.NSIG:
  803. raise ValueError('illegal signal number: %r' % signalnum)
  804. # still possible to crash on one of libev's asserts:
  805. # 1) "libev: ev_signal_start called with illegal signal number"
  806. # EV_NSIG might be different from signal.NSIG on some platforms
  807. # 2) "libev: a signal must not be attached to two different loops"
  808. # we probably could check that in LIBEV_EMBED mode, but not in general
  809. watcher.__init__(self, loop, ref=ref, priority=priority, args=(signalnum, ))
  810. class idle(watcher):
  811. _watcher_type = 'ev_idle'
  812. class prepare(watcher):
  813. _watcher_type = 'ev_prepare'
  814. class check(watcher):
  815. _watcher_type = 'ev_check'
  816. class fork(watcher):
  817. _watcher_type = 'ev_fork'
  818. class async(watcher):
  819. _watcher_type = 'ev_async'
  820. def send(self):
  821. libev.ev_async_send(self.loop._ptr, self._watcher)
  822. @property
  823. def pending(self):
  824. return True if libev.ev_async_pending(self._watcher) else False
  825. class child(watcher):
  826. _watcher_type = 'ev_child'
  827. def __init__(self, loop, pid, trace=0, ref=True):
  828. if not loop.default:
  829. raise TypeError('child watchers are only available on the default loop')
  830. loop.install_sigchld()
  831. watcher.__init__(self, loop, ref=ref, args=(pid, trace))
  832. def _format(self):
  833. return ' pid=%r rstatus=%r' % (self.pid, self.rstatus)
  834. @property
  835. def pid(self):
  836. return self._watcher.pid
  837. @property
  838. def rpid(self, ):
  839. return self._watcher.rpid
  840. @rpid.setter
  841. def rpid(self, value):
  842. self._watcher.rpid = value
  843. @property
  844. def rstatus(self):
  845. return self._watcher.rstatus
  846. @rstatus.setter
  847. def rstatus(self, value):
  848. self._watcher.rstatus = value
  849. class stat(watcher):
  850. _watcher_type = 'ev_stat'
  851. @staticmethod
  852. def _encode_path(path):
  853. if isinstance(path, bytes):
  854. return path
  855. # encode for the filesystem. Not all systems (e.g., Unix)
  856. # will have an encoding specified
  857. encoding = sys.getfilesystemencoding() or 'utf-8'
  858. try:
  859. path = path.encode(encoding, 'surrogateescape')
  860. except LookupError:
  861. # Can't encode it, and the error handler doesn't
  862. # exist. Probably on Python 2 with an astral character.
  863. # Not sure how to handle this.
  864. raise UnicodeEncodeError("Can't encode path to filesystem encoding")
  865. return path
  866. def __init__(self, _loop, path, interval=0.0, ref=True, priority=None):
  867. # Store the encoded path in the same attribute that corecext does
  868. self._paths = self._encode_path(path)
  869. # Keep the original path to avoid re-encoding, especially on Python 3
  870. self._path = path
  871. # Although CFFI would automatically convert a bytes object into a char* when
  872. # calling ev_stat_init(..., char*, ...), on PyPy the char* pointer is not
  873. # guaranteed to live past the function call. On CPython, only with a constant/interned
  874. # bytes object is the pointer guaranteed to last path the function call. (And since
  875. # Python 3 is pretty much guaranteed to produce a newly-encoded bytes object above, thats
  876. # rarely the case). Therefore, we must keep a reference to the produced cdata object
  877. # so that the struct ev_stat_watcher's `path` pointer doesn't become invalid/deallocated
  878. self._cpath = ffi.new('char[]', self._paths)
  879. watcher.__init__(self, _loop, ref=ref, priority=priority,
  880. args=(self._cpath,
  881. interval))
  882. @property
  883. def path(self):
  884. return self._path
  885. @property
  886. def attr(self):
  887. if not self._watcher.attr.st_nlink:
  888. return
  889. return self._watcher.attr
  890. @property
  891. def prev(self):
  892. if not self._watcher.prev.st_nlink:
  893. return
  894. return self._watcher.prev
  895. @property
  896. def interval(self):
  897. return self._watcher.interval
  898. # All watcher subclasses must be declared above. Now we do some
  899. # initialization; this is not only a minor optimization, it protects
  900. # against later runtime typos and attribute errors
  901. watcher._init_subclasses()
  902. def _syserr_cb(msg):
  903. try:
  904. msg = ffi.string(msg)
  905. __SYSERR_CALLBACK(msg, ffi.errno)
  906. except:
  907. set_syserr_cb(None)
  908. raise # let cffi print the traceback
  909. _syserr_cb._cb = ffi.callback("void(*)(char *msg)", _syserr_cb)
  910. def set_syserr_cb(callback):
  911. global __SYSERR_CALLBACK
  912. if callback is None:
  913. libev.ev_set_syserr_cb(ffi.NULL)
  914. __SYSERR_CALLBACK = None
  915. elif callable(callback):
  916. libev.ev_set_syserr_cb(_syserr_cb._cb)
  917. __SYSERR_CALLBACK = callback
  918. else:
  919. raise TypeError('Expected callable or None, got %r' % (callback, ))
  920. __SYSERR_CALLBACK = None
  921. LIBEV_EMBED = True