stream.pyx 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046
  1. cdef enum:
  2. __PREALLOCED_BUFS = 4
  3. @cython.no_gc_clear
  4. @cython.freelist(DEFAULT_FREELIST_SIZE)
  5. cdef class _StreamWriteContext:
  6. # used to hold additional write request information for uv_write
  7. cdef:
  8. uv.uv_write_t req
  9. list buffers
  10. uv.uv_buf_t uv_bufs_sml[__PREALLOCED_BUFS]
  11. Py_buffer py_bufs_sml[__PREALLOCED_BUFS]
  12. bint py_bufs_sml_inuse
  13. uv.uv_buf_t* uv_bufs
  14. Py_buffer* py_bufs
  15. size_t py_bufs_len
  16. uv.uv_buf_t* uv_bufs_start
  17. size_t uv_bufs_len
  18. UVStream stream
  19. bint closed
  20. cdef free_bufs(self):
  21. cdef size_t i
  22. if self.uv_bufs is not NULL:
  23. PyMem_RawFree(self.uv_bufs)
  24. self.uv_bufs = NULL
  25. if UVLOOP_DEBUG:
  26. if self.py_bufs_sml_inuse:
  27. raise RuntimeError(
  28. '_StreamWriteContext.close: uv_bufs != NULL and '
  29. 'py_bufs_sml_inuse is True')
  30. if self.py_bufs is not NULL:
  31. for i from 0 <= i < self.py_bufs_len:
  32. PyBuffer_Release(&self.py_bufs[i])
  33. PyMem_RawFree(self.py_bufs)
  34. self.py_bufs = NULL
  35. if UVLOOP_DEBUG:
  36. if self.py_bufs_sml_inuse:
  37. raise RuntimeError(
  38. '_StreamWriteContext.close: py_bufs != NULL and '
  39. 'py_bufs_sml_inuse is True')
  40. if self.py_bufs_sml_inuse:
  41. for i from 0 <= i < self.py_bufs_len:
  42. PyBuffer_Release(&self.py_bufs_sml[i])
  43. self.py_bufs_sml_inuse = 0
  44. self.py_bufs_len = 0
  45. self.buffers = None
  46. cdef close(self):
  47. if self.closed:
  48. return
  49. self.closed = 1
  50. self.free_bufs()
  51. Py_DECREF(self)
  52. cdef advance_uv_buf(self, size_t sent):
  53. # Advance the pointer to first uv_buf and the
  54. # pointer to first byte in that buffer.
  55. #
  56. # We do this after a "uv_try_write" call, which
  57. # sometimes sends only a portion of data.
  58. # We then call "advance_uv_buf" on the write
  59. # context, and reuse it in a "uv_write" call.
  60. cdef:
  61. uv.uv_buf_t* buf
  62. size_t idx
  63. for idx from 0 <= idx < self.uv_bufs_len:
  64. buf = &self.uv_bufs_start[idx]
  65. if buf.len > sent:
  66. buf.len -= sent
  67. buf.base = buf.base + sent
  68. self.uv_bufs_start = buf
  69. self.uv_bufs_len -= idx
  70. return
  71. else:
  72. sent -= self.uv_bufs_start[idx].len
  73. if UVLOOP_DEBUG:
  74. if sent < 0:
  75. raise RuntimeError('fatal: sent < 0 in advance_uv_buf')
  76. raise RuntimeError('fatal: Could not advance _StreamWriteContext')
  77. @staticmethod
  78. cdef _StreamWriteContext new(UVStream stream, list buffers):
  79. cdef:
  80. _StreamWriteContext ctx
  81. int uv_bufs_idx = 0
  82. size_t py_bufs_len = 0
  83. int i
  84. Py_buffer* p_pybufs
  85. uv.uv_buf_t* p_uvbufs
  86. ctx = _StreamWriteContext.__new__(_StreamWriteContext)
  87. ctx.stream = None
  88. ctx.closed = 1
  89. ctx.py_bufs_len = 0
  90. ctx.py_bufs_sml_inuse = 0
  91. ctx.uv_bufs = NULL
  92. ctx.py_bufs = NULL
  93. ctx.buffers = buffers
  94. ctx.stream = stream
  95. if len(buffers) <= __PREALLOCED_BUFS:
  96. # We've got a small number of buffers to write, don't
  97. # need to use malloc.
  98. ctx.py_bufs_sml_inuse = 1
  99. p_pybufs = <Py_buffer*>&ctx.py_bufs_sml
  100. p_uvbufs = <uv.uv_buf_t*>&ctx.uv_bufs_sml
  101. else:
  102. for buf in buffers:
  103. if UVLOOP_DEBUG:
  104. if not isinstance(buf, (bytes, bytearray, memoryview)):
  105. raise RuntimeError(
  106. 'invalid data in writebuf: an instance of '
  107. 'bytes, bytearray or memoryview was expected, '
  108. 'got {}'.format(type(buf)))
  109. if not PyBytes_CheckExact(buf):
  110. py_bufs_len += 1
  111. if py_bufs_len > 0:
  112. ctx.py_bufs = <Py_buffer*>PyMem_RawMalloc(
  113. py_bufs_len * sizeof(Py_buffer))
  114. if ctx.py_bufs is NULL:
  115. raise MemoryError()
  116. ctx.uv_bufs = <uv.uv_buf_t*>PyMem_RawMalloc(
  117. len(buffers) * sizeof(uv.uv_buf_t))
  118. if ctx.uv_bufs is NULL:
  119. raise MemoryError()
  120. p_pybufs = ctx.py_bufs
  121. p_uvbufs = ctx.uv_bufs
  122. py_bufs_len = 0
  123. for buf in buffers:
  124. if PyBytes_CheckExact(buf):
  125. # We can only use this hack for bytes since it's
  126. # immutable. For everything else it is only safe to
  127. # use buffer protocol.
  128. p_uvbufs[uv_bufs_idx].base = PyBytes_AS_STRING(buf)
  129. p_uvbufs[uv_bufs_idx].len = Py_SIZE(buf)
  130. else:
  131. try:
  132. PyObject_GetBuffer(
  133. buf, &p_pybufs[py_bufs_len], PyBUF_SIMPLE)
  134. except Exception:
  135. # This shouldn't ever happen, as `UVStream._buffer_write`
  136. # casts non-bytes objects to `memoryviews`.
  137. ctx.py_bufs_len = py_bufs_len
  138. ctx.free_bufs()
  139. raise
  140. p_uvbufs[uv_bufs_idx].base = <char*>p_pybufs[py_bufs_len].buf
  141. p_uvbufs[uv_bufs_idx].len = p_pybufs[py_bufs_len].len
  142. py_bufs_len += 1
  143. uv_bufs_idx += 1
  144. ctx.uv_bufs_start = p_uvbufs
  145. ctx.uv_bufs_len = uv_bufs_idx
  146. ctx.py_bufs_len = py_bufs_len
  147. ctx.req.data = <void*> ctx
  148. if UVLOOP_DEBUG:
  149. stream._loop._debug_stream_write_ctx_total += 1
  150. stream._loop._debug_stream_write_ctx_cnt += 1
  151. # Do incref after everything else is done.
  152. # Under no circumstances we want `ctx` to be GCed while
  153. # libuv is still working with `ctx.uv_bufs`.
  154. Py_INCREF(ctx)
  155. ctx.closed = 0
  156. return ctx
  157. def __dealloc__(self):
  158. if not self.closed:
  159. # Because we do an INCREF in _StreamWriteContext.new,
  160. # __dealloc__ shouldn't ever happen with `self.closed == 1`
  161. raise RuntimeError(
  162. 'open _StreamWriteContext is being deallocated')
  163. if UVLOOP_DEBUG:
  164. if self.stream is not None:
  165. self.stream._loop._debug_stream_write_ctx_cnt -= 1
  166. self.stream = None
  167. @cython.no_gc_clear
  168. cdef class UVStream(UVBaseTransport):
  169. def __cinit__(self):
  170. self.__shutting_down = 0
  171. self.__reading = 0
  172. self.__read_error_close = 0
  173. self.__protocol_type = ProtocolType.SIMPLE
  174. self._protocol_get_buffer = None
  175. self._protocol_buffer_updated = None
  176. self._eof = 0
  177. self._buffer = []
  178. self._buffer_size = 0
  179. self._read_pybuf_acquired = False
  180. cdef _set_protocol(self, object protocol):
  181. if protocol is None:
  182. raise TypeError('protocol is required')
  183. UVBaseTransport._set_protocol(self, protocol)
  184. if isinstance(protocol, SSLProtocol):
  185. self.__protocol_type = ProtocolType.SSL_PROTOCOL
  186. elif (hasattr(protocol, 'get_buffer') and
  187. not isinstance(protocol, aio_Protocol)):
  188. try:
  189. self._protocol_get_buffer = protocol.get_buffer
  190. self._protocol_buffer_updated = protocol.buffer_updated
  191. self.__protocol_type = ProtocolType.BUFFERED
  192. except AttributeError:
  193. pass
  194. else:
  195. self.__protocol_type = ProtocolType.SIMPLE
  196. cdef _clear_protocol(self):
  197. UVBaseTransport._clear_protocol(self)
  198. self._protocol_get_buffer = None
  199. self._protocol_buffer_updated = None
  200. self.__protocol_type = ProtocolType.SIMPLE
  201. cdef inline _shutdown(self):
  202. cdef int err
  203. if self.__shutting_down:
  204. return
  205. self.__shutting_down = 1
  206. self._ensure_alive()
  207. self._shutdown_req.data = <void*> self
  208. err = uv.uv_shutdown(&self._shutdown_req,
  209. <uv.uv_stream_t*> self._handle,
  210. __uv_stream_on_shutdown)
  211. if err < 0:
  212. exc = convert_error(err)
  213. self._fatal_error(exc, True)
  214. return
  215. cdef inline _accept(self, UVStream server):
  216. cdef int err
  217. self._ensure_alive()
  218. err = uv.uv_accept(<uv.uv_stream_t*>server._handle,
  219. <uv.uv_stream_t*>self._handle)
  220. if err < 0:
  221. exc = convert_error(err)
  222. self._fatal_error(exc, True)
  223. return
  224. self._on_accept()
  225. cdef inline _close_on_read_error(self):
  226. self.__read_error_close = 1
  227. cdef bint _is_reading(self):
  228. return self.__reading
  229. cdef _start_reading(self):
  230. cdef int err
  231. if self._closing:
  232. return
  233. self._ensure_alive()
  234. if self.__reading:
  235. return
  236. if self.__protocol_type == ProtocolType.SIMPLE:
  237. err = uv.uv_read_start(<uv.uv_stream_t*>self._handle,
  238. __loop_alloc_buffer,
  239. __uv_stream_on_read)
  240. else:
  241. err = uv.uv_read_start(<uv.uv_stream_t *> self._handle,
  242. __uv_stream_buffered_alloc,
  243. __uv_stream_buffered_on_read)
  244. if err < 0:
  245. exc = convert_error(err)
  246. self._fatal_error(exc, True)
  247. return
  248. else:
  249. # UVStream must live until the read callback is called
  250. self.__reading_started()
  251. cdef inline __reading_started(self):
  252. if self.__reading:
  253. return
  254. self.__reading = 1
  255. Py_INCREF(self)
  256. cdef inline __reading_stopped(self):
  257. if not self.__reading:
  258. return
  259. self.__reading = 0
  260. Py_DECREF(self)
  261. cdef _stop_reading(self):
  262. cdef int err
  263. if not self.__reading:
  264. return
  265. self._ensure_alive()
  266. # From libuv docs:
  267. # This function is idempotent and may be safely
  268. # called on a stopped stream.
  269. err = uv.uv_read_stop(<uv.uv_stream_t*>self._handle)
  270. if err < 0:
  271. exc = convert_error(err)
  272. self._fatal_error(exc, True)
  273. return
  274. else:
  275. self.__reading_stopped()
  276. cdef inline Py_ssize_t _try_write(self, object data) except -2:
  277. # Returns number of bytes written.
  278. # -1 - in case of fatal errors
  279. cdef:
  280. Py_ssize_t written
  281. bint used_buf = 0
  282. Py_buffer py_buf
  283. void* buf
  284. Py_ssize_t blen
  285. int saved_errno
  286. int fd
  287. if (<uv.uv_stream_t*>self._handle).write_queue_size != 0:
  288. raise RuntimeError(
  289. 'UVStream._try_write called with data in uv buffers')
  290. if PyBytes_CheckExact(data):
  291. # We can only use this hack for bytes since it's
  292. # immutable. For everything else it is only safe to
  293. # use buffer protocol.
  294. buf = <void*>PyBytes_AS_STRING(data)
  295. blen = Py_SIZE(data)
  296. else:
  297. PyObject_GetBuffer(data, &py_buf, PyBUF_SIMPLE)
  298. used_buf = 1
  299. buf = py_buf.buf
  300. blen = py_buf.len
  301. if blen == 0:
  302. if used_buf:
  303. PyBuffer_Release(&py_buf)
  304. # Empty data, do nothing.
  305. return 0
  306. fd = self._fileno()
  307. # Use `unistd.h/write` directly, it's faster than
  308. # uv_try_write -- less layers of code. The error
  309. # checking logic is copied from libuv.
  310. written = system.write(fd, buf, blen)
  311. while written == -1 and (
  312. errno.errno == errno.EINTR or
  313. (system.PLATFORM_IS_APPLE and
  314. errno.errno == errno.EPROTOTYPE)):
  315. # From libuv code (unix/stream.c):
  316. # Due to a possible kernel bug at least in OS X 10.10 "Yosemite",
  317. # EPROTOTYPE can be returned while trying to write to a socket
  318. # that is shutting down. If we retry the write, we should get
  319. # the expected EPIPE instead.
  320. written = system.write(fd, buf, blen)
  321. saved_errno = errno.errno
  322. if used_buf:
  323. PyBuffer_Release(&py_buf)
  324. if written < 0:
  325. if saved_errno in (errno.EAGAIN, system.EWOULDBLOCK):
  326. return 0
  327. else:
  328. exc = convert_error(-saved_errno)
  329. self._fatal_error(exc, True)
  330. return -1
  331. if UVLOOP_DEBUG:
  332. self._loop._debug_stream_write_tries += 1
  333. return written
  334. cdef inline _buffer_write(self, object data):
  335. cdef Py_ssize_t dlen
  336. if not PyBytes_CheckExact(data):
  337. data = memoryview(data).cast('b')
  338. dlen = len(data)
  339. if not dlen:
  340. return
  341. self._buffer_size += dlen
  342. self._buffer.append(data)
  343. cdef inline _initiate_write(self):
  344. cdef bint all_sent
  345. if (not self._protocol_paused and
  346. (<uv.uv_stream_t*>self._handle).write_queue_size == 0):
  347. # Fast-path. If:
  348. # - the protocol isn't yet paused,
  349. # - there is no data in libuv buffers for this stream,
  350. #
  351. # Then:
  352. # - Try to write all buffered data right now.
  353. all_sent = self._exec_write()
  354. if UVLOOP_DEBUG:
  355. if self._buffer_size != 0 or self._buffer:
  356. raise RuntimeError(
  357. '_buffer_size is not 0 after a successful _exec_write')
  358. # There is no need to call `_queue_write` anymore,
  359. # as `uv_write` should be called already.
  360. if not all_sent:
  361. # If not all of the data was sent successfully,
  362. # we might need to pause the protocol.
  363. self._maybe_pause_protocol()
  364. elif self._buffer_size > 0:
  365. self._maybe_pause_protocol()
  366. self._loop._queue_write(self)
  367. cdef inline bint _exec_write(self) except -1:
  368. # Returns True if all data from self._buffers has been sent,
  369. # False - otherwise
  370. cdef:
  371. int err
  372. Py_ssize_t buf_len
  373. Py_ssize_t sent
  374. _StreamWriteContext ctx = None
  375. if self._closed:
  376. # If the handle is closed, just return, it's too
  377. # late to do anything.
  378. return False
  379. buf_len = len(self._buffer)
  380. if not buf_len:
  381. return True
  382. if (<uv.uv_stream_t*>self._handle).write_queue_size == 0:
  383. # libuv internal write buffers for this stream are empty.
  384. if buf_len == 1:
  385. # If we only have one piece of data to send, let's
  386. # use our fast implementation of try_write.
  387. data = self._buffer[0]
  388. sent = self._try_write(data)
  389. if sent == len(data):
  390. # The most likely and latency sensitive outcome goes first,
  391. # all data was successfully written.
  392. self._buffer_size = 0
  393. self._buffer.clear()
  394. # on_write will call "maybe_resume_protocol".
  395. self._on_write()
  396. return True
  397. elif sent > 0:
  398. if PyBytes_CheckExact(data):
  399. # Cast bytes to memoryview to avoid copying
  400. # data that wasn't sent.
  401. data = memoryview(data)
  402. data = data[sent:]
  403. self._buffer_size -= sent
  404. self._buffer[0] = data
  405. elif sent == -1:
  406. # A `self._fatal_error` was called.
  407. # It might not raise an exception under some
  408. # conditions.
  409. self._buffer_size = 0
  410. self._buffer.clear()
  411. if not self._closing:
  412. # This should never happen.
  413. raise RuntimeError(
  414. 'stream is open after UVStream._try_write '
  415. 'returned None')
  416. return False
  417. # At this point it's either data was sent partially,
  418. # or an EAGAIN has happened.
  419. else:
  420. ctx = _StreamWriteContext.new(self, self._buffer)
  421. err = uv.uv_try_write(<uv.uv_stream_t*>self._handle,
  422. ctx.uv_bufs_start,
  423. ctx.uv_bufs_len)
  424. if err > 0:
  425. # Some data was successfully sent.
  426. if <size_t>err == self._buffer_size:
  427. # Everything was sent.
  428. ctx.close()
  429. self._buffer.clear()
  430. self._buffer_size = 0
  431. # on_write will call "maybe_resume_protocol".
  432. self._on_write()
  433. return True
  434. try:
  435. # Advance pointers to uv_bufs in `ctx`,
  436. # we will reuse it soon for a uv_write
  437. # call.
  438. ctx.advance_uv_buf(<ssize_t>err)
  439. except Exception as ex: # This should never happen.
  440. # Let's try to close the `ctx` anyways.
  441. ctx.close()
  442. self._fatal_error(ex, True)
  443. self._buffer.clear()
  444. self._buffer_size = 0
  445. return False
  446. elif err != uv.UV_EAGAIN:
  447. ctx.close()
  448. exc = convert_error(err)
  449. self._fatal_error(exc, True)
  450. self._buffer.clear()
  451. self._buffer_size = 0
  452. return False
  453. # fall through
  454. if ctx is None:
  455. ctx = _StreamWriteContext.new(self, self._buffer)
  456. err = uv.uv_write(&ctx.req,
  457. <uv.uv_stream_t*>self._handle,
  458. ctx.uv_bufs_start,
  459. ctx.uv_bufs_len,
  460. __uv_stream_on_write)
  461. self._buffer_size = 0
  462. # Can't use `_buffer.clear()` here: `ctx` holds a reference to
  463. # the `_buffer`.
  464. self._buffer = []
  465. if err < 0:
  466. # close write context
  467. ctx.close()
  468. exc = convert_error(err)
  469. self._fatal_error(exc, True)
  470. return False
  471. self._maybe_resume_protocol()
  472. return False
  473. cdef size_t _get_write_buffer_size(self):
  474. if self._handle is NULL:
  475. return 0
  476. return ((<uv.uv_stream_t*>self._handle).write_queue_size +
  477. self._buffer_size)
  478. cdef _close(self):
  479. try:
  480. if self._read_pybuf_acquired:
  481. # Should never happen. libuv always calls uv_alloc/uv_read
  482. # in pairs.
  483. self._loop.call_exception_handler({
  484. 'transport': self,
  485. 'message': 'XXX: an allocated buffer in transport._close()'
  486. })
  487. self._read_pybuf_acquired = 0
  488. PyBuffer_Release(&self._read_pybuf)
  489. self._stop_reading()
  490. finally:
  491. UVSocketHandle._close(<UVHandle>self)
  492. cdef inline _on_accept(self):
  493. # Ultimately called by __uv_stream_on_listen.
  494. self._init_protocol()
  495. cdef inline _on_eof(self):
  496. # Any exception raised here will be caught in
  497. # __uv_stream_on_read.
  498. try:
  499. meth = self._protocol.eof_received
  500. except AttributeError:
  501. keep_open = False
  502. else:
  503. keep_open = run_in_context(self.context, meth)
  504. if keep_open:
  505. # We're keeping the connection open so the
  506. # protocol can write more, but we still can't
  507. # receive more, so remove the reader callback.
  508. self._stop_reading()
  509. else:
  510. self.close()
  511. cdef inline _on_write(self):
  512. self._maybe_resume_protocol()
  513. if not self._get_write_buffer_size():
  514. if self._closing:
  515. self._schedule_call_connection_lost(None)
  516. elif self._eof:
  517. self._shutdown()
  518. cdef inline _init(self, Loop loop, object protocol, Server server,
  519. object waiter, object context):
  520. self.context = context
  521. self._set_protocol(protocol)
  522. self._start_init(loop)
  523. if server is not None:
  524. self._set_server(server)
  525. if waiter is not None:
  526. self._set_waiter(waiter)
  527. cdef inline _on_connect(self, object exc):
  528. # Called from __tcp_connect_callback (tcp.pyx) and
  529. # __pipe_connect_callback (pipe.pyx).
  530. if exc is None:
  531. self._init_protocol()
  532. else:
  533. if self._waiter is None:
  534. self._fatal_error(exc, False, "connect failed")
  535. elif self._waiter.cancelled():
  536. # Connect call was cancelled; just close the transport
  537. # silently.
  538. self._close()
  539. elif self._waiter.done():
  540. self._fatal_error(exc, False, "connect failed")
  541. else:
  542. self._waiter.set_exception(exc)
  543. self._close()
  544. # === Public API ===
  545. def __repr__(self):
  546. return '<{} closed={} reading={} {:#x}>'.format(
  547. self.__class__.__name__,
  548. self._closed,
  549. self.__reading,
  550. id(self))
  551. cpdef write(self, object buf):
  552. self._ensure_alive()
  553. if self._eof:
  554. raise RuntimeError('Cannot call write() after write_eof()')
  555. if not buf:
  556. return
  557. if self._conn_lost:
  558. self._conn_lost += 1
  559. return
  560. self._buffer_write(buf)
  561. self._initiate_write()
  562. def writelines(self, bufs):
  563. self._ensure_alive()
  564. if self._eof:
  565. raise RuntimeError('Cannot call writelines() after write_eof()')
  566. if self._conn_lost:
  567. self._conn_lost += 1
  568. return
  569. for buf in bufs:
  570. self._buffer_write(buf)
  571. self._initiate_write()
  572. def write_eof(self):
  573. self._ensure_alive()
  574. if self._eof:
  575. return
  576. self._eof = 1
  577. if not self._get_write_buffer_size():
  578. self._shutdown()
  579. def can_write_eof(self):
  580. return True
  581. def is_reading(self):
  582. return self._is_reading()
  583. def pause_reading(self):
  584. if self._closing or not self._is_reading():
  585. return
  586. self._stop_reading()
  587. def resume_reading(self):
  588. if self._is_reading() or self._closing:
  589. return
  590. self._start_reading()
  591. cdef void __uv_stream_on_shutdown(uv.uv_shutdown_t* req,
  592. int status) noexcept with gil:
  593. # callback for uv_shutdown
  594. if req.data is NULL:
  595. aio_logger.error(
  596. 'UVStream.shutdown callback called with NULL req.data, status=%r',
  597. status)
  598. return
  599. cdef UVStream stream = <UVStream> req.data
  600. if status < 0 and status != uv.UV_ECANCELED:
  601. # From libuv source code:
  602. # The ECANCELED error code is a lie, the shutdown(2) syscall is a
  603. # fait accompli at this point. Maybe we should revisit this in
  604. # v0.11. A possible reason for leaving it unchanged is that it
  605. # informs the callee that the handle has been destroyed.
  606. if UVLOOP_DEBUG:
  607. stream._loop._debug_stream_shutdown_errors_total += 1
  608. exc = convert_error(status)
  609. stream._fatal_error(
  610. exc, False, "error status in uv_stream_t.shutdown callback")
  611. return
  612. cdef inline bint __uv_stream_on_read_common(
  613. UVStream sc,
  614. Loop loop,
  615. ssize_t nread,
  616. ):
  617. if sc._closed:
  618. # The stream was closed, there is no reason to
  619. # do any work now.
  620. sc.__reading_stopped() # Just in case.
  621. return True
  622. if nread == uv.UV_EOF:
  623. # From libuv docs:
  624. # The callee is responsible for stopping closing the stream
  625. # when an error happens by calling uv_read_stop() or uv_close().
  626. # Trying to read from the stream again is undefined.
  627. try:
  628. if UVLOOP_DEBUG:
  629. loop._debug_stream_read_eof_total += 1
  630. sc._stop_reading()
  631. sc._on_eof()
  632. except BaseException as ex:
  633. if UVLOOP_DEBUG:
  634. loop._debug_stream_read_eof_cb_errors_total += 1
  635. sc._fatal_error(ex, False)
  636. finally:
  637. return True
  638. if nread == 0:
  639. # From libuv docs:
  640. # nread might be 0, which does not indicate an error or EOF.
  641. # This is equivalent to EAGAIN or EWOULDBLOCK under read(2).
  642. return True
  643. if nread < 0:
  644. # From libuv docs:
  645. # The callee is responsible for stopping closing the stream
  646. # when an error happens by calling uv_read_stop() or uv_close().
  647. # Trying to read from the stream again is undefined.
  648. #
  649. # Therefore, we're closing the stream. Since "UVHandle._close()"
  650. # doesn't raise exceptions unless uvloop is built with DEBUG=1,
  651. # we don't need try...finally here.
  652. if UVLOOP_DEBUG:
  653. loop._debug_stream_read_errors_total += 1
  654. if sc.__read_error_close:
  655. # Used for getting notified when a pipe is closed.
  656. # See WriteUnixTransport for the explanation.
  657. sc._on_eof()
  658. return True
  659. exc = convert_error(nread)
  660. sc._fatal_error(
  661. exc, False, "error status in uv_stream_t.read callback")
  662. return True
  663. return False
  664. cdef inline void __uv_stream_on_read_impl(
  665. uv.uv_stream_t* stream,
  666. ssize_t nread,
  667. const uv.uv_buf_t* buf,
  668. ):
  669. cdef:
  670. UVStream sc = <UVStream>stream.data
  671. Loop loop = sc._loop
  672. # It's OK to free the buffer early, since nothing will
  673. # be able to touch it until this method is done.
  674. __loop_free_buffer(loop)
  675. if __uv_stream_on_read_common(sc, loop, nread):
  676. return
  677. try:
  678. if UVLOOP_DEBUG:
  679. loop._debug_stream_read_cb_total += 1
  680. run_in_context1(
  681. sc.context,
  682. sc._protocol_data_received,
  683. loop._recv_buffer[:nread],
  684. )
  685. except BaseException as exc:
  686. if UVLOOP_DEBUG:
  687. loop._debug_stream_read_cb_errors_total += 1
  688. sc._fatal_error(exc, False)
  689. cdef inline void __uv_stream_on_write_impl(
  690. uv.uv_write_t* req,
  691. int status,
  692. ):
  693. cdef:
  694. _StreamWriteContext ctx = <_StreamWriteContext> req.data
  695. UVStream stream = <UVStream>ctx.stream
  696. ctx.close()
  697. if stream._closed:
  698. # The stream was closed, there is nothing to do.
  699. # Even if there is an error, like EPIPE, there
  700. # is no reason to report it.
  701. return
  702. if status < 0:
  703. if UVLOOP_DEBUG:
  704. stream._loop._debug_stream_write_errors_total += 1
  705. exc = convert_error(status)
  706. stream._fatal_error(
  707. exc, False, "error status in uv_stream_t.write callback")
  708. return
  709. try:
  710. stream._on_write()
  711. except BaseException as exc:
  712. if UVLOOP_DEBUG:
  713. stream._loop._debug_stream_write_cb_errors_total += 1
  714. stream._fatal_error(exc, False)
  715. cdef void __uv_stream_on_read(
  716. uv.uv_stream_t* stream,
  717. ssize_t nread,
  718. const uv.uv_buf_t* buf,
  719. ) noexcept with gil:
  720. if __ensure_handle_data(<uv.uv_handle_t*>stream,
  721. "UVStream read callback") == 0:
  722. return
  723. # Don't need try-finally, __uv_stream_on_read_impl is void
  724. __uv_stream_on_read_impl(stream, nread, buf)
  725. cdef void __uv_stream_on_write(
  726. uv.uv_write_t* req,
  727. int status,
  728. ) noexcept with gil:
  729. if UVLOOP_DEBUG:
  730. if req.data is NULL:
  731. aio_logger.error(
  732. 'UVStream.write callback called with NULL req.data, status=%r',
  733. status)
  734. return
  735. # Don't need try-finally, __uv_stream_on_write_impl is void
  736. __uv_stream_on_write_impl(req, status)
  737. cdef void __uv_stream_buffered_alloc(
  738. uv.uv_handle_t* stream,
  739. size_t suggested_size,
  740. uv.uv_buf_t* uvbuf,
  741. ) noexcept with gil:
  742. if __ensure_handle_data(<uv.uv_handle_t*>stream,
  743. "UVStream alloc buffer callback") == 0:
  744. return
  745. cdef UVStream sc = <UVStream>stream.data
  746. # Fast pass for our own SSLProtocol
  747. # avoid python calls, memoryviews, context enter/exit, etc
  748. if sc.__protocol_type == ProtocolType.SSL_PROTOCOL:
  749. try:
  750. (<SSLProtocol>sc._protocol).get_buffer_impl(
  751. suggested_size, &uvbuf.base, &uvbuf.len)
  752. return
  753. except BaseException as exc:
  754. # Can't call 'sc._fatal_error' or 'sc._close', libuv will SF.
  755. # We'll do it later in __uv_stream_buffered_on_read when we
  756. # receive UV_ENOBUFS.
  757. uvbuf.len = 0
  758. uvbuf.base = NULL
  759. return
  760. cdef:
  761. Py_buffer* pybuf = &sc._read_pybuf
  762. int got_buf = 0
  763. if sc._read_pybuf_acquired:
  764. uvbuf.len = 0
  765. uvbuf.base = NULL
  766. return
  767. sc._read_pybuf_acquired = 0
  768. try:
  769. buf = run_in_context1(
  770. sc.context,
  771. sc._protocol_get_buffer,
  772. suggested_size,
  773. )
  774. PyObject_GetBuffer(buf, pybuf, PyBUF_WRITABLE)
  775. got_buf = 1
  776. except BaseException as exc:
  777. # Can't call 'sc._fatal_error' or 'sc._close', libuv will SF.
  778. # We'll do it later in __uv_stream_buffered_on_read when we
  779. # receive UV_ENOBUFS.
  780. uvbuf.len = 0
  781. uvbuf.base = NULL
  782. return
  783. if not pybuf.len:
  784. uvbuf.len = 0
  785. uvbuf.base = NULL
  786. if got_buf:
  787. PyBuffer_Release(pybuf)
  788. return
  789. sc._read_pybuf_acquired = 1
  790. uvbuf.base = <char*>pybuf.buf
  791. uvbuf.len = pybuf.len
  792. cdef void __uv_stream_buffered_on_read(
  793. uv.uv_stream_t* stream,
  794. ssize_t nread,
  795. const uv.uv_buf_t* buf,
  796. ) noexcept with gil:
  797. if __ensure_handle_data(<uv.uv_handle_t*>stream,
  798. "UVStream buffered read callback") == 0:
  799. return
  800. cdef:
  801. UVStream sc = <UVStream>stream.data
  802. Loop loop = sc._loop
  803. Py_buffer* pybuf = &sc._read_pybuf
  804. if nread == uv.UV_ENOBUFS:
  805. sc._fatal_error(
  806. RuntimeError(
  807. 'unhandled error (or an empty buffer) in get_buffer()'),
  808. False)
  809. return
  810. try:
  811. # When our own SSLProtocol is used, we get buffer pointer directly,
  812. # through SSLProtocol.get_buffer_impl, not through Py_Buffer interface.
  813. # Therefore sc._read_pybuf_acquired is always False for SSLProtocol.
  814. if (nread > 0 and
  815. sc.__protocol_type == ProtocolType.BUFFERED and
  816. not sc._read_pybuf_acquired):
  817. # From libuv docs:
  818. # nread is > 0 if there is data available or < 0 on error. When
  819. # we’ve reached EOF, nread will be set to UV_EOF. When
  820. # nread < 0, the buf parameter might not point to a valid
  821. # buffer; in that case buf.len and buf.base are both set to 0.
  822. raise RuntimeError(
  823. f'no python buffer is allocated in on_read; nread={nread}')
  824. if nread == 0:
  825. # From libuv docs:
  826. # nread might be 0, which does not indicate an error or EOF.
  827. # This is equivalent to EAGAIN or EWOULDBLOCK under read(2).
  828. return
  829. if __uv_stream_on_read_common(sc, loop, nread):
  830. return
  831. if UVLOOP_DEBUG:
  832. loop._debug_stream_read_cb_total += 1
  833. if sc.__protocol_type == ProtocolType.SSL_PROTOCOL:
  834. Context_Enter(sc.context)
  835. try:
  836. (<SSLProtocol>sc._protocol).buffer_updated_impl(nread)
  837. finally:
  838. Context_Exit(sc.context)
  839. else:
  840. run_in_context1(sc.context, sc._protocol_buffer_updated, nread)
  841. except BaseException as exc:
  842. if UVLOOP_DEBUG:
  843. loop._debug_stream_read_cb_errors_total += 1
  844. sc._fatal_error(exc, False)
  845. finally:
  846. if sc._read_pybuf_acquired:
  847. sc._read_pybuf_acquired = 0
  848. PyBuffer_Release(pybuf)