Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 

248 linhas
7.5 KiB

  1. cdef __pipe_init_uv_handle(UVStream handle, Loop loop):
  2. cdef int err
  3. handle._handle = <uv.uv_handle_t*>PyMem_RawMalloc(sizeof(uv.uv_pipe_t))
  4. if handle._handle is NULL:
  5. handle._abort_init()
  6. raise MemoryError()
  7. # Initialize pipe handle with ipc=0.
  8. # ipc=1 means that libuv will use recvmsg/sendmsg
  9. # instead of recv/send.
  10. err = uv.uv_pipe_init(handle._loop.uvloop,
  11. <uv.uv_pipe_t*>handle._handle,
  12. 0)
  13. # UV_HANDLE_READABLE allows calling uv_read_start() on this pipe
  14. # even if it is O_WRONLY, see also #317, libuv/libuv#2058
  15. handle._handle.flags |= uv.UV_INTERNAL_HANDLE_READABLE
  16. if err < 0:
  17. handle._abort_init()
  18. raise convert_error(err)
  19. handle._finish_init()
  20. cdef __pipe_open(UVStream handle, int fd):
  21. cdef int err
  22. err = uv.uv_pipe_open(<uv.uv_pipe_t *>handle._handle,
  23. <uv.uv_os_fd_t>fd)
  24. if err < 0:
  25. exc = convert_error(err)
  26. raise exc
  27. cdef __pipe_get_socket(UVSocketHandle handle):
  28. fileno = handle._fileno()
  29. return PseudoSocket(uv.AF_UNIX, uv.SOCK_STREAM, 0, fileno)
  30. @cython.no_gc_clear
  31. cdef class UnixServer(UVStreamServer):
  32. @staticmethod
  33. cdef UnixServer new(Loop loop, object protocol_factory, Server server,
  34. object backlog,
  35. object ssl,
  36. object ssl_handshake_timeout,
  37. object ssl_shutdown_timeout):
  38. cdef UnixServer handle
  39. handle = UnixServer.__new__(UnixServer)
  40. handle._init(loop, protocol_factory, server, backlog,
  41. ssl, ssl_handshake_timeout, ssl_shutdown_timeout)
  42. __pipe_init_uv_handle(<UVStream>handle, loop)
  43. return handle
  44. cdef _new_socket(self):
  45. return __pipe_get_socket(<UVSocketHandle>self)
  46. cdef _open(self, int sockfd):
  47. self._ensure_alive()
  48. __pipe_open(<UVStream>self, sockfd)
  49. self._mark_as_open()
  50. cdef bind(self, str path):
  51. cdef int err
  52. self._ensure_alive()
  53. err = uv.uv_pipe_bind(<uv.uv_pipe_t *>self._handle,
  54. path.encode())
  55. if err < 0:
  56. exc = convert_error(err)
  57. self._fatal_error(exc, True)
  58. return
  59. self._mark_as_open()
  60. cdef UVStream _make_new_transport(self, object protocol, object waiter,
  61. object context):
  62. cdef UnixTransport tr
  63. tr = UnixTransport.new(self._loop, protocol, self._server, waiter,
  64. context)
  65. return <UVStream>tr
  66. cdef _close(self):
  67. sock = self._fileobj
  68. if sock is not None and sock in self._loop._unix_server_sockets:
  69. path = sock.getsockname()
  70. else:
  71. path = None
  72. UVStreamServer._close(self)
  73. if path is not None:
  74. prev_ino = self._loop._unix_server_sockets[sock]
  75. del self._loop._unix_server_sockets[sock]
  76. try:
  77. if os_stat(path).st_ino == prev_ino:
  78. os_unlink(path)
  79. except FileNotFoundError:
  80. pass
  81. except OSError as err:
  82. aio_logger.error('Unable to clean up listening UNIX socket '
  83. '%r: %r', path, err)
  84. @cython.no_gc_clear
  85. cdef class UnixTransport(UVStream):
  86. @staticmethod
  87. cdef UnixTransport new(Loop loop, object protocol, Server server,
  88. object waiter, object context):
  89. cdef UnixTransport handle
  90. handle = UnixTransport.__new__(UnixTransport)
  91. handle._init(loop, protocol, server, waiter, context)
  92. __pipe_init_uv_handle(<UVStream>handle, loop)
  93. return handle
  94. cdef _new_socket(self):
  95. return __pipe_get_socket(<UVSocketHandle>self)
  96. cdef _open(self, int sockfd):
  97. __pipe_open(<UVStream>self, sockfd)
  98. cdef connect(self, char* addr):
  99. cdef _PipeConnectRequest req
  100. req = _PipeConnectRequest(self._loop, self)
  101. req.connect(addr)
  102. @cython.no_gc_clear
  103. cdef class ReadUnixTransport(UVStream):
  104. @staticmethod
  105. cdef ReadUnixTransport new(Loop loop, object protocol, Server server,
  106. object waiter):
  107. cdef ReadUnixTransport handle
  108. handle = ReadUnixTransport.__new__(ReadUnixTransport)
  109. # This is only used in connect_read_pipe() and subprocess_shell/exec()
  110. # directly, we could simply copy the current context.
  111. handle._init(loop, protocol, server, waiter, Context_CopyCurrent())
  112. __pipe_init_uv_handle(<UVStream>handle, loop)
  113. return handle
  114. cdef _new_socket(self):
  115. return __pipe_get_socket(<UVSocketHandle>self)
  116. cdef _open(self, int sockfd):
  117. __pipe_open(<UVStream>self, sockfd)
  118. def get_write_buffer_limits(self):
  119. raise NotImplementedError
  120. def set_write_buffer_limits(self, high=None, low=None):
  121. raise NotImplementedError
  122. def get_write_buffer_size(self):
  123. raise NotImplementedError
  124. def write(self, data):
  125. raise NotImplementedError
  126. def writelines(self, list_of_data):
  127. raise NotImplementedError
  128. def write_eof(self):
  129. raise NotImplementedError
  130. def can_write_eof(self):
  131. raise NotImplementedError
  132. def abort(self):
  133. raise NotImplementedError
  134. @cython.no_gc_clear
  135. cdef class WriteUnixTransport(UVStream):
  136. @staticmethod
  137. cdef WriteUnixTransport new(Loop loop, object protocol, Server server,
  138. object waiter):
  139. cdef WriteUnixTransport handle
  140. handle = WriteUnixTransport.__new__(WriteUnixTransport)
  141. # We listen for read events on write-end of the pipe. When
  142. # the read-end is close, the uv_stream_t.read callback will
  143. # receive an error -- we want to silence that error, and just
  144. # close the transport.
  145. handle._close_on_read_error()
  146. # This is only used in connect_write_pipe() and subprocess_shell/exec()
  147. # directly, we could simply copy the current context.
  148. handle._init(loop, protocol, server, waiter, Context_CopyCurrent())
  149. __pipe_init_uv_handle(<UVStream>handle, loop)
  150. return handle
  151. cdef _new_socket(self):
  152. return __pipe_get_socket(<UVSocketHandle>self)
  153. cdef _open(self, int sockfd):
  154. __pipe_open(<UVStream>self, sockfd)
  155. def pause_reading(self):
  156. raise NotImplementedError
  157. def resume_reading(self):
  158. raise NotImplementedError
  159. cdef class _PipeConnectRequest(UVRequest):
  160. cdef:
  161. UnixTransport transport
  162. uv.uv_connect_t _req_data
  163. def __cinit__(self, loop, transport):
  164. self.request = <uv.uv_req_t*> &self._req_data
  165. self.request.data = <void*>self
  166. self.transport = transport
  167. cdef connect(self, char* addr):
  168. # uv_pipe_connect returns void
  169. uv.uv_pipe_connect(<uv.uv_connect_t*>self.request,
  170. <uv.uv_pipe_t*>self.transport._handle,
  171. addr,
  172. __pipe_connect_callback)
  173. cdef void __pipe_connect_callback(
  174. uv.uv_connect_t* req,
  175. int status,
  176. ) noexcept with gil:
  177. cdef:
  178. _PipeConnectRequest wrapper
  179. UnixTransport transport
  180. wrapper = <_PipeConnectRequest> req.data
  181. transport = wrapper.transport
  182. if status < 0:
  183. exc = convert_error(status)
  184. else:
  185. exc = None
  186. try:
  187. transport._on_connect(exc)
  188. except BaseException as ex:
  189. wrapper.transport._fatal_error(ex, False)
  190. finally:
  191. wrapper.on_done()