rloop 0.3.0__tar.gz → 0.3.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. {rloop-0.3.0 → rloop-0.3.1}/Cargo.lock +1 -1
  2. {rloop-0.3.0 → rloop-0.3.1}/Cargo.toml +1 -1
  3. {rloop-0.3.0 → rloop-0.3.1}/PKG-INFO +1 -1
  4. {rloop-0.3.0 → rloop-0.3.1}/src/tcp.rs +34 -13
  5. {rloop-0.3.0 → rloop-0.3.1}/LICENSE +0 -0
  6. {rloop-0.3.0 → rloop-0.3.1}/README.md +0 -0
  7. {rloop-0.3.0 → rloop-0.3.1}/pyproject.toml +0 -0
  8. {rloop-0.3.0 → rloop-0.3.1}/rloop/__init__.py +0 -0
  9. {rloop-0.3.0 → rloop-0.3.1}/rloop/_compat.py +0 -0
  10. {rloop-0.3.0 → rloop-0.3.1}/rloop/_rloop.pyi +0 -0
  11. {rloop-0.3.0 → rloop-0.3.1}/rloop/exc.py +0 -0
  12. {rloop-0.3.0 → rloop-0.3.1}/rloop/futures.py +0 -0
  13. {rloop-0.3.0 → rloop-0.3.1}/rloop/loop.py +0 -0
  14. {rloop-0.3.0 → rloop-0.3.1}/rloop/server.py +0 -0
  15. {rloop-0.3.0 → rloop-0.3.1}/rloop/subprocess.py +0 -0
  16. {rloop-0.3.0 → rloop-0.3.1}/rloop/transports.py +0 -0
  17. {rloop-0.3.0 → rloop-0.3.1}/rloop/utils.py +0 -0
  18. {rloop-0.3.0 → rloop-0.3.1}/src/event_loop.rs +0 -0
  19. {rloop-0.3.0 → rloop-0.3.1}/src/handles.rs +0 -0
  20. {rloop-0.3.0 → rloop-0.3.1}/src/io.rs +0 -0
  21. {rloop-0.3.0 → rloop-0.3.1}/src/lib.rs +0 -0
  22. {rloop-0.3.0 → rloop-0.3.1}/src/log.rs +0 -0
  23. {rloop-0.3.0 → rloop-0.3.1}/src/py.rs +0 -0
  24. {rloop-0.3.0 → rloop-0.3.1}/src/server.rs +0 -0
  25. {rloop-0.3.0 → rloop-0.3.1}/src/sock.rs +0 -0
  26. {rloop-0.3.0 → rloop-0.3.1}/src/time.rs +0 -0
  27. {rloop-0.3.0 → rloop-0.3.1}/src/udp.rs +0 -0
  28. {rloop-0.3.0 → rloop-0.3.1}/src/utils.rs +0 -0
  29. {rloop-0.3.0 → rloop-0.3.1}/tests/conftest.py +0 -0
  30. {rloop-0.3.0 → rloop-0.3.1}/tests/tcp/__init__.py +0 -0
  31. {rloop-0.3.0 → rloop-0.3.1}/tests/tcp/test_tcp_conn.py +0 -0
  32. {rloop-0.3.0 → rloop-0.3.1}/tests/tcp/test_tcp_server.py +0 -0
  33. {rloop-0.3.0 → rloop-0.3.1}/tests/test_handles.py +0 -0
  34. {rloop-0.3.0 → rloop-0.3.1}/tests/test_sockets.py +0 -0
  35. {rloop-0.3.0 → rloop-0.3.1}/tests/udp/test_udp.py +0 -0
@@ -144,7 +144,7 @@ dependencies = [
144
144
 
145
145
  [[package]]
146
146
  name = "rloop"
147
- version = "0.3.0"
147
+ version = "0.3.1"
148
148
  dependencies = [
149
149
  "anyhow",
150
150
  "libc",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "rloop"
3
- version = "0.3.0"
3
+ version = "0.3.1"
4
4
  description = "An asyncio event loop implemented in Rust"
5
5
  authors = ["Giovanni Barillari <g@baro.dev>"]
6
6
  license = "BSD-3-Clause"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rloop
3
- Version: 0.3.0
3
+ Version: 0.3.1
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: BSD License
@@ -24,6 +24,11 @@ use crate::{
24
24
  utils::syscall,
25
25
  };
26
26
 
27
+ // PyO3 removed private CPython's APIs
28
+ unsafe extern "C" {
29
+ fn _PyBytes_Resize(bytes: *mut *mut pyo3::ffi::PyObject, newsize: pyo3::ffi::Py_ssize_t) -> std::os::raw::c_int;
30
+ }
31
+
27
32
  pub(crate) struct TCPServer {
28
33
  pub fd: i32,
29
34
  sfamily: i32,
@@ -557,25 +562,41 @@ pub(crate) struct TCPReadHandle {
557
562
 
558
563
  impl TCPReadHandle {
559
564
  #[inline]
560
- fn recv_direct(&self, py: Python, transport: &TCPTransport, buf: &mut [u8]) -> (Option<Py<PyAny>>, bool) {
565
+ fn recv_direct(&self, py: Python, transport: &TCPTransport) -> (Option<Py<PyAny>>, bool, bool) {
566
+ const BUF_MAXSIZE: usize = 262_144;
567
+ //: alloc an uninitialized `PyBytes` and read into it: single copy (kernel -> bytes), matching asyncio/CPython's `sock.recv`
568
+ let mut obj =
569
+ unsafe { pyo3::ffi::PyBytes_FromStringAndSize(std::ptr::null(), BUF_MAXSIZE as pyo3::ffi::Py_ssize_t) };
570
+ if obj.is_null() {
571
+ unsafe { pyo3::ffi::PyErr_Clear() };
572
+ return (None, false, false);
573
+ }
574
+ let buf = unsafe { std::slice::from_raw_parts_mut(pyo3::ffi::PyBytes_AsString(obj).cast::<u8>(), BUF_MAXSIZE) };
575
+
561
576
  let (read, closed) = self.read_into(&mut transport.state.borrow_mut().stream, buf);
562
577
  if read > 0 {
563
- let rbuf = &buf[..read];
564
- let pydata = unsafe { PyBytes::from_ptr(py, rbuf.as_ptr(), read) };
565
- return (Some(pydata.into_any().unbind()), closed);
578
+ if read < BUF_MAXSIZE && unsafe { _PyBytes_Resize(&mut obj, read as pyo3::ffi::Py_ssize_t) } != 0 {
579
+ unsafe { pyo3::ffi::PyErr_Clear() };
580
+ return (None, closed, false);
581
+ }
582
+ let pydata = unsafe { Bound::from_owned_ptr(py, obj).unbind() };
583
+ // `read == BUF_MAXSIZE` means the buffer filled, so more data may be waiting.
584
+ return (Some(pydata), closed, read == BUF_MAXSIZE);
566
585
  }
567
- (None, closed)
586
+ unsafe { pyo3::ffi::Py_DECREF(obj) };
587
+ (None, closed, false)
568
588
  }
569
589
 
570
590
  #[inline]
571
- fn recv_buffered(&self, py: Python, transport: &TCPTransport) -> (Option<Py<PyAny>>, bool) {
591
+ fn recv_buffered(&self, py: Python, transport: &TCPTransport) -> (Option<Py<PyAny>>, bool, bool) {
572
592
  let pybuf: PyBuffer<u8> = PyBuffer::get(&transport.protom_buf_get.bind(py).call1((-1,)).unwrap()).unwrap();
593
+ let max_len = pybuf.len_bytes();
573
594
 
574
595
  let (read, closed) = if pybuf.is_c_contiguous() && !pybuf.readonly() {
575
596
  // Read straight into the protocol's buffer, no intermediate allocation or
576
597
  // copy. The GIL is held for the whole call, so nothing else can touch the
577
598
  // buffer concurrently, and we only access it through this slice.
578
- let buf = unsafe { std::slice::from_raw_parts_mut(pybuf.buf_ptr().cast::<u8>(), pybuf.len_bytes()) };
599
+ let buf = unsafe { std::slice::from_raw_parts_mut(pybuf.buf_ptr().cast::<u8>(), max_len) };
579
600
  self.read_into(&mut transport.state.borrow_mut().stream, buf)
580
601
  } else {
581
602
  // Fallback for non-contiguous/read-only buffers: copy through a temp Vec.
@@ -588,9 +609,9 @@ impl TCPReadHandle {
588
609
  };
589
610
 
590
611
  if read > 0 {
591
- return (Some(read.into_py_any(py).unwrap()), closed);
612
+ return (Some(read.into_py_any(py).unwrap()), closed, read == max_len);
592
613
  }
593
- (None, closed)
614
+ (None, closed, false)
594
615
  }
595
616
 
596
617
  #[inline(always)]
@@ -628,7 +649,7 @@ impl TCPReadHandle {
628
649
  }
629
650
 
630
651
  impl Handle for TCPReadHandle {
631
- fn run(&self, py: Python, event_loop: &EventLoop, state: &mut EventLoopRunState) {
652
+ fn run(&self, py: Python, event_loop: &EventLoop, _state: &mut EventLoopRunState) {
632
653
  let pytransport = event_loop.get_tcp_transport(self.fd, py);
633
654
  let transport = pytransport.borrow(py);
634
655
 
@@ -636,14 +657,14 @@ impl Handle for TCPReadHandle {
636
657
  // otherwise we won't get another readable event from the poller
637
658
  let mut close = false;
638
659
  loop {
639
- let (data, eof) = match transport.proto_buffered {
660
+ let (data, eof, full) = match transport.proto_buffered {
640
661
  true => self.recv_buffered(py, &transport),
641
- false => self.recv_direct(py, &transport, &mut state.read_buf),
662
+ false => self.recv_direct(py, &transport),
642
663
  };
643
664
 
644
665
  if let Some(data) = data {
645
666
  _ = transport.protom_recv_data.call1(py, (data,));
646
- if !eof {
667
+ if !eof && full {
647
668
  continue;
648
669
  }
649
670
  }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes