From 6d7ba58f880be618ade07f8ea080fe8c4bf8a896 Mon Sep 17 00:00:00 2001 From: cyfraeviolae Date: Wed, 3 Apr 2024 03:10:44 -0400 Subject: venv --- .../site-packages/uvloop/handles/poll.pyx | 233 +++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 venv/lib/python3.11/site-packages/uvloop/handles/poll.pyx (limited to 'venv/lib/python3.11/site-packages/uvloop/handles/poll.pyx') diff --git a/venv/lib/python3.11/site-packages/uvloop/handles/poll.pyx b/venv/lib/python3.11/site-packages/uvloop/handles/poll.pyx new file mode 100644 index 0000000..fca5981 --- /dev/null +++ b/venv/lib/python3.11/site-packages/uvloop/handles/poll.pyx @@ -0,0 +1,233 @@ +@cython.no_gc_clear +cdef class UVPoll(UVHandle): + cdef _init(self, Loop loop, int fd): + cdef int err + + self._start_init(loop) + + self._handle = PyMem_RawMalloc(sizeof(uv.uv_poll_t)) + if self._handle is NULL: + self._abort_init() + raise MemoryError() + + err = uv.uv_poll_init(self._loop.uvloop, + self._handle, fd) + if err < 0: + self._abort_init() + raise convert_error(err) + + self._finish_init() + + self.fd = fd + self.reading_handle = None + self.writing_handle = None + + @staticmethod + cdef UVPoll new(Loop loop, int fd): + cdef UVPoll handle + handle = UVPoll.__new__(UVPoll) + handle._init(loop, fd) + return handle + + cdef int is_active(self): + return (self.reading_handle is not None or + self.writing_handle is not None) + + cdef inline _poll_start(self, int flags): + cdef int err + + self._ensure_alive() + + err = uv.uv_poll_start( + self._handle, + flags, + __on_uvpoll_event) + + if err < 0: + exc = convert_error(err) + self._fatal_error(exc, True) + return + + cdef inline _poll_stop(self): + cdef int err + + if not self._is_alive(): + return + + err = uv.uv_poll_stop(self._handle) + if err < 0: + exc = convert_error(err) + self._fatal_error(exc, True) + return + + cdef: + int backend_id + system.epoll_event dummy_event + + if system.PLATFORM_IS_LINUX: + # libuv doesn't remove the FD from epoll immediately + # after uv_poll_stop or uv_poll_close, causing hard + # to debug issue with dup-ed file descriptors causing + # CPU burn in epoll/epoll_ctl: + # https://github.com/MagicStack/uvloop/issues/61 + # + # It's safe though to manually call epoll_ctl here, + # after calling uv_poll_stop. + + backend_id = uv.uv_backend_fd(self._loop.uvloop) + if backend_id != -1: + memset(&dummy_event, 0, sizeof(dummy_event)) + system.epoll_ctl( + backend_id, + system.EPOLL_CTL_DEL, + self.fd, + &dummy_event) # ignore errors + + cdef is_reading(self): + return self._is_alive() and self.reading_handle is not None + + cdef is_writing(self): + return self._is_alive() and self.writing_handle is not None + + cdef start_reading(self, Handle callback): + cdef: + int mask = 0 + + if self.reading_handle is None: + # not reading right now, setup the handle + + mask = uv.UV_READABLE + if self.writing_handle is not None: + # are we writing right now? + mask |= uv.UV_WRITABLE + + self._poll_start(mask) + else: + self.reading_handle._cancel() + + self.reading_handle = callback + + cdef start_writing(self, Handle callback): + cdef: + int mask = 0 + + if self.writing_handle is None: + # not writing right now, setup the handle + + mask = uv.UV_WRITABLE + if self.reading_handle is not None: + # are we reading right now? + mask |= uv.UV_READABLE + + self._poll_start(mask) + else: + self.writing_handle._cancel() + + self.writing_handle = callback + + cdef stop_reading(self): + if self.reading_handle is None: + return False + + self.reading_handle._cancel() + self.reading_handle = None + + if self.writing_handle is None: + self.stop() + else: + self._poll_start(uv.UV_WRITABLE) + + return True + + cdef stop_writing(self): + if self.writing_handle is None: + return False + + self.writing_handle._cancel() + self.writing_handle = None + + if self.reading_handle is None: + self.stop() + else: + self._poll_start(uv.UV_READABLE) + + return True + + cdef stop(self): + if self.reading_handle is not None: + self.reading_handle._cancel() + self.reading_handle = None + + if self.writing_handle is not None: + self.writing_handle._cancel() + self.writing_handle = None + + self._poll_stop() + + cdef _close(self): + if self.is_active(): + self.stop() + + UVHandle._close(self) + + cdef _fatal_error(self, exc, throw, reason=None): + try: + if self.reading_handle is not None: + try: + self.reading_handle._run() + except BaseException as ex: + self._loop._handle_exception(ex) + self.reading_handle = None + + if self.writing_handle is not None: + try: + self.writing_handle._run() + except BaseException as ex: + self._loop._handle_exception(ex) + self.writing_handle = None + + finally: + self._close() + + +cdef void __on_uvpoll_event( + uv.uv_poll_t* handle, + int status, + int events, +) noexcept with gil: + + if __ensure_handle_data(handle, "UVPoll callback") == 0: + return + + cdef: + UVPoll poll = handle.data + + if status < 0: + exc = convert_error(status) + poll._fatal_error(exc, False) + return + + if ((events & (uv.UV_READABLE | uv.UV_DISCONNECT)) and + poll.reading_handle is not None): + + try: + if UVLOOP_DEBUG: + poll._loop._poll_read_events_total += 1 + poll.reading_handle._run() + except BaseException as ex: + if UVLOOP_DEBUG: + poll._loop._poll_read_cb_errors_total += 1 + poll._error(ex, False) + # continue code execution + + if ((events & (uv.UV_WRITABLE | uv.UV_DISCONNECT)) and + poll.writing_handle is not None): + + try: + if UVLOOP_DEBUG: + poll._loop._poll_write_events_total += 1 + poll.writing_handle._run() + except BaseException as ex: + if UVLOOP_DEBUG: + poll._loop._poll_write_cb_errors_total += 1 + poll._error(ex, False) -- cgit v1.2.3