summaryrefslogtreecommitdiff
path: root/venv/lib/python3.11/site-packages/uvloop/handles/handle.pyx
diff options
context:
space:
mode:
authorcyfraeviolae <cyfraeviolae>2024-04-03 03:17:55 -0400
committercyfraeviolae <cyfraeviolae>2024-04-03 03:17:55 -0400
commit12cf076118570eebbff08c6b3090e0d4798447a1 (patch)
tree3ba25e17e3c3a5e82316558ba3864b955919ff72 /venv/lib/python3.11/site-packages/uvloop/handles/handle.pyx
parentc45662ff3923b34614ddcc8feb9195541166dcc5 (diff)
no venv
Diffstat (limited to 'venv/lib/python3.11/site-packages/uvloop/handles/handle.pyx')
-rw-r--r--venv/lib/python3.11/site-packages/uvloop/handles/handle.pyx395
1 files changed, 0 insertions, 395 deletions
diff --git a/venv/lib/python3.11/site-packages/uvloop/handles/handle.pyx b/venv/lib/python3.11/site-packages/uvloop/handles/handle.pyx
deleted file mode 100644
index 6efe375..0000000
--- a/venv/lib/python3.11/site-packages/uvloop/handles/handle.pyx
+++ /dev/null
@@ -1,395 +0,0 @@
-cdef class UVHandle:
- """A base class for all libuv handles.
-
- Automatically manages memory deallocation and closing.
-
- Important:
-
- 1. call "_ensure_alive()" before calling any libuv functions on
- your handles.
-
- 2. call "__ensure_handle_data" in *all* libuv handle callbacks.
- """
-
- def __cinit__(self):
- self._closed = 0
- self._inited = 0
- self._has_handle = 1
- self._handle = NULL
- self._loop = None
- self._source_traceback = None
-
- def __init__(self):
- raise TypeError(
- '{} is not supposed to be instantiated from Python'.format(
- self.__class__.__name__))
-
- def __dealloc__(self):
- if UVLOOP_DEBUG:
- if self._loop is not None:
- if self._inited:
- self._loop._debug_handles_current.subtract([
- self.__class__.__name__])
- else:
- # No "@cython.no_gc_clear" decorator on this UVHandle
- raise RuntimeError(
- '{} without @no_gc_clear; loop was set to None by GC'
- .format(self.__class__.__name__))
-
- if self._handle is NULL:
- return
-
- # -> When we're at this point, something is wrong <-
-
- if self._handle.loop is NULL:
- # The handle wasn't initialized with "uv_{handle}_init"
- self._closed = 1
- self._free()
- raise RuntimeError(
- '{} is open in __dealloc__ with loop set to NULL'
- .format(self.__class__.__name__))
-
- if self._closed:
- # So _handle is not NULL and self._closed == 1?
- raise RuntimeError(
- '{}.__dealloc__: _handle is NULL, _closed == 1'.format(
- self.__class__.__name__))
-
- # The handle is dealloced while open. Let's try to close it.
- # Situations when this is possible include unhandled exceptions,
- # errors during Handle.__cinit__/__init__ etc.
- if self._inited:
- self._handle.data = NULL
- uv.uv_close(self._handle, __uv_close_handle_cb) # void; no errors
- self._handle = NULL
- self._warn_unclosed()
- else:
- # The handle was allocated, but not initialized
- self._closed = 1
- self._free()
-
- cdef _free(self):
- if self._handle == NULL:
- return
-
- if UVLOOP_DEBUG and self._inited:
- self._loop._debug_uv_handles_freed += 1
-
- PyMem_RawFree(self._handle)
- self._handle = NULL
-
- cdef _warn_unclosed(self):
- if self._source_traceback is not None:
- try:
- tb = ''.join(tb_format_list(self._source_traceback))
- tb = 'object created at (most recent call last):\n{}'.format(
- tb.rstrip())
- except Exception as ex:
- msg = (
- 'unclosed resource {!r}; could not serialize '
- 'debug traceback: {}: {}'
- ).format(self, type(ex).__name__, ex)
- else:
- msg = 'unclosed resource {!r}; {}'.format(self, tb)
- else:
- msg = 'unclosed resource {!r}'.format(self)
- warnings_warn(msg, ResourceWarning)
-
- cdef inline _abort_init(self):
- if self._handle is not NULL:
- self._free()
-
- try:
- if UVLOOP_DEBUG:
- name = self.__class__.__name__
- if self._inited:
- raise RuntimeError(
- '_abort_init: {}._inited is set'.format(name))
- if self._closed:
- raise RuntimeError(
- '_abort_init: {}._closed is set'.format(name))
- finally:
- self._closed = 1
-
- cdef inline _finish_init(self):
- self._inited = 1
- if self._has_handle == 1:
- self._handle.data = <void*>self
- if self._loop._debug:
- self._source_traceback = extract_stack()
- if UVLOOP_DEBUG:
- cls_name = self.__class__.__name__
- self._loop._debug_uv_handles_total += 1
- self._loop._debug_handles_total.update([cls_name])
- self._loop._debug_handles_current.update([cls_name])
-
- cdef inline _start_init(self, Loop loop):
- if UVLOOP_DEBUG:
- if self._loop is not None:
- raise RuntimeError(
- '{}._start_init can only be called once'.format(
- self.__class__.__name__))
-
- self._loop = loop
-
- cdef inline bint _is_alive(self):
- cdef bint res
- res = self._closed != 1 and self._inited == 1
- if UVLOOP_DEBUG:
- if res and self._has_handle == 1:
- name = self.__class__.__name__
- if self._handle is NULL:
- raise RuntimeError(
- '{} is alive, but _handle is NULL'.format(name))
- if self._loop is None:
- raise RuntimeError(
- '{} is alive, but _loop is None'.format(name))
- if self._handle.loop is not self._loop.uvloop:
- raise RuntimeError(
- '{} is alive, but _handle.loop is not '
- 'initialized'.format(name))
- if self._handle.data is not <void*>self:
- raise RuntimeError(
- '{} is alive, but _handle.data is not '
- 'initialized'.format(name))
- return res
-
- cdef inline _ensure_alive(self):
- if not self._is_alive():
- raise RuntimeError(
- 'unable to perform operation on {!r}; '
- 'the handler is closed'.format(self))
-
- cdef _fatal_error(self, exc, throw, reason=None):
- # Fatal error means an error that was returned by the
- # underlying libuv handle function. We usually can't
- # recover from that, hence we just close the handle.
- self._close()
-
- if throw or self._loop is None:
- raise exc
- else:
- self._loop._handle_exception(exc)
-
- cdef _error(self, exc, throw):
- # A non-fatal error is usually an error that was caught
- # by the handler, but was originated in the client code
- # (not in libuv). In this case we either want to simply
- # raise or log it.
- if throw or self._loop is None:
- raise exc
- else:
- self._loop._handle_exception(exc)
-
- cdef _close(self):
- if self._closed == 1:
- return
-
- self._closed = 1
-
- if self._handle is NULL:
- return
-
- if UVLOOP_DEBUG:
- if self._handle.data is NULL:
- raise RuntimeError(
- '{}._close: _handle.data is NULL'.format(
- self.__class__.__name__))
-
- if <object>self._handle.data is not self:
- raise RuntimeError(
- '{}._close: _handle.data is not UVHandle/self'.format(
- self.__class__.__name__))
-
- if uv.uv_is_closing(self._handle):
- raise RuntimeError(
- '{}._close: uv_is_closing() is true'.format(
- self.__class__.__name__))
-
- # We want the handle wrapper (UVHandle) to stay alive until
- # the closing callback fires.
- Py_INCREF(self)
- uv.uv_close(self._handle, __uv_close_handle_cb) # void; no errors
-
- def __repr__(self):
- return '<{} closed={} {:#x}>'.format(
- self.__class__.__name__,
- self._closed,
- id(self))
-
-
-cdef class UVSocketHandle(UVHandle):
-
- def __cinit__(self):
- self._fileobj = None
- self.__cached_socket = None
-
- cdef _fileno(self):
- cdef:
- int fd
- int err
-
- self._ensure_alive()
- err = uv.uv_fileno(self._handle, <uv.uv_os_fd_t*>&fd)
- if err < 0:
- raise convert_error(err)
-
- return fd
-
- cdef _new_socket(self):
- raise NotImplementedError
-
- cdef inline _get_socket(self):
- if self.__cached_socket is not None:
- return self.__cached_socket
-
- if not self._is_alive():
- return None
-
- self.__cached_socket = self._new_socket()
- if UVLOOP_DEBUG:
- # We don't "dup" for the "__cached_socket".
- assert self.__cached_socket.fileno() == self._fileno()
- return self.__cached_socket
-
- cdef inline _attach_fileobj(self, object file):
- # When we create a TCP/PIPE/etc connection/server based on
- # a Python file object, we need to close the file object when
- # the uv handle is closed.
- socket_inc_io_ref(file)
- self._fileobj = file
-
- cdef _close(self):
- if self.__cached_socket is not None:
- (<PseudoSocket>self.__cached_socket)._fd = -1
-
- UVHandle._close(self)
-
- try:
- # This code will only run for transports created from
- # Python sockets, i.e. with `loop.create_server(sock=sock)` etc.
- if self._fileobj is not None:
- if isinstance(self._fileobj, socket_socket):
- # Detaching the socket object is the ideal solution:
- # * libuv will actually close the FD;
- # * detach() call will reset FD for the Python socket
- # object, which means that it won't be closed 2nd time
- # when the socket object is GCed.
- #
- # No need to call `socket_dec_io_ref()`, as
- # `socket.detach()` ignores `socket._io_refs`.
- self._fileobj.detach()
- else:
- try:
- # `socket.close()` will raise an EBADF because libuv
- # has already closed the underlying FD.
- self._fileobj.close()
- except OSError as ex:
- if ex.errno != errno_EBADF:
- raise
- except Exception as ex:
- self._loop.call_exception_handler({
- 'exception': ex,
- 'transport': self,
- 'message': f'could not close attached file object '
- f'{self._fileobj!r}',
- })
- finally:
- self._fileobj = None
-
- cdef _open(self, int sockfd):
- raise NotImplementedError
-
-
-cdef inline bint __ensure_handle_data(uv.uv_handle_t* handle,
- const char* handle_ctx):
-
- cdef Loop loop
-
- if UVLOOP_DEBUG:
- if handle.loop is NULL:
- raise RuntimeError(
- 'handle.loop is NULL in __ensure_handle_data')
-
- if handle.loop.data is NULL:
- raise RuntimeError(
- 'handle.loop.data is NULL in __ensure_handle_data')
-
- if handle.data is NULL:
- loop = <Loop>handle.loop.data
- loop.call_exception_handler({
- 'message': '{} called with handle.data == NULL'.format(
- handle_ctx.decode('latin-1'))
- })
- return 0
-
- if handle.data is NULL:
- # The underlying UVHandle object was GCed with an open uv_handle_t.
- loop = <Loop>handle.loop.data
- loop.call_exception_handler({
- 'message': '{} called after destroying the UVHandle'.format(
- handle_ctx.decode('latin-1'))
- })
- return 0
-
- return 1
-
-
-cdef void __uv_close_handle_cb(uv.uv_handle_t* handle) noexcept with gil:
- cdef UVHandle h
-
- if handle.data is NULL:
- # The original UVHandle is long dead. Just free the mem of
- # the uv_handle_t* handler.
-
- if UVLOOP_DEBUG:
- if handle.loop == NULL or handle.loop.data == NULL:
- raise RuntimeError(
- '__uv_close_handle_cb: handle.loop is invalid')
- (<Loop>handle.loop.data)._debug_uv_handles_freed += 1
-
- PyMem_RawFree(handle)
- else:
- h = <UVHandle>handle.data
- try:
- if UVLOOP_DEBUG:
- if not h._has_handle:
- raise RuntimeError(
- 'has_handle=0 in __uv_close_handle_cb')
- h._loop._debug_handles_closed.update([
- h.__class__.__name__])
- h._free()
- finally:
- Py_DECREF(h) # Was INCREFed in UVHandle._close
-
-
-cdef void __close_all_handles(Loop loop):
- uv.uv_walk(loop.uvloop,
- __uv_walk_close_all_handles_cb,
- <void*>loop) # void
-
-
-cdef void __uv_walk_close_all_handles_cb(
- uv.uv_handle_t* handle,
- void* arg,
-) noexcept with gil:
-
- cdef:
- Loop loop = <Loop>arg
- UVHandle h
-
- if uv.uv_is_closing(handle):
- # The handle is closed or is closing.
- return
-
- if handle.data is NULL:
- # This shouldn't happen. Ever.
- loop.call_exception_handler({
- 'message': 'handle.data is NULL in __close_all_handles_cb'
- })
- return
-
- h = <UVHandle>handle.data
- if not h._closed:
- h._warn_unclosed()
- h._close()