rloop 0.1.1__tar.gz → 0.1.3__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 (34) hide show
  1. {rloop-0.1.1 → rloop-0.1.3}/Cargo.lock +48 -96
  2. {rloop-0.1.1 → rloop-0.1.3}/Cargo.toml +4 -4
  3. {rloop-0.1.1 → rloop-0.1.3}/PKG-INFO +1 -1
  4. {rloop-0.1.1 → rloop-0.1.3}/rloop/server.py +1 -1
  5. {rloop-0.1.1 → rloop-0.1.3}/src/event_loop.rs +211 -186
  6. {rloop-0.1.1 → rloop-0.1.3}/src/tcp.rs +3 -2
  7. {rloop-0.1.1 → rloop-0.1.3}/LICENSE +0 -0
  8. {rloop-0.1.1 → rloop-0.1.3}/README.md +0 -0
  9. {rloop-0.1.1 → rloop-0.1.3}/pyproject.toml +0 -0
  10. {rloop-0.1.1 → rloop-0.1.3}/rloop/__init__.py +0 -0
  11. {rloop-0.1.1 → rloop-0.1.3}/rloop/_compat.py +0 -0
  12. {rloop-0.1.1 → rloop-0.1.3}/rloop/_rloop.pyi +0 -0
  13. {rloop-0.1.1 → rloop-0.1.3}/rloop/exc.py +0 -0
  14. {rloop-0.1.1 → rloop-0.1.3}/rloop/futures.py +0 -0
  15. {rloop-0.1.1 → rloop-0.1.3}/rloop/loop.py +0 -0
  16. {rloop-0.1.1 → rloop-0.1.3}/rloop/subprocess.py +0 -0
  17. {rloop-0.1.1 → rloop-0.1.3}/rloop/transports.py +0 -0
  18. {rloop-0.1.1 → rloop-0.1.3}/rloop/utils.py +0 -0
  19. {rloop-0.1.1 → rloop-0.1.3}/src/handles.rs +0 -0
  20. {rloop-0.1.1 → rloop-0.1.3}/src/io.rs +0 -0
  21. {rloop-0.1.1 → rloop-0.1.3}/src/lib.rs +0 -0
  22. {rloop-0.1.1 → rloop-0.1.3}/src/log.rs +0 -0
  23. {rloop-0.1.1 → rloop-0.1.3}/src/py.rs +0 -0
  24. {rloop-0.1.1 → rloop-0.1.3}/src/server.rs +0 -0
  25. {rloop-0.1.1 → rloop-0.1.3}/src/sock.rs +0 -0
  26. {rloop-0.1.1 → rloop-0.1.3}/src/time.rs +0 -0
  27. {rloop-0.1.1 → rloop-0.1.3}/src/utils.rs +0 -0
  28. {rloop-0.1.1 → rloop-0.1.3}/tests/conftest.py +0 -0
  29. {rloop-0.1.1 → rloop-0.1.3}/tests/tcp/__init__.py +0 -0
  30. {rloop-0.1.1 → rloop-0.1.3}/tests/tcp/test_tcp_conn.py +0 -0
  31. {rloop-0.1.1 → rloop-0.1.3}/tests/tcp/test_tcp_server.py +0 -0
  32. {rloop-0.1.1 → rloop-0.1.3}/tests/test_handles.py +0 -0
  33. {rloop-0.1.1 → rloop-0.1.3}/tests/test_sockets.py +0 -0
  34. {rloop-0.1.1 → rloop-0.1.3}/tests/udp/test_udp.py +0 -0
@@ -14,52 +14,20 @@ version = "1.4.0"
14
14
  source = "registry+https://github.com/rust-lang/crates.io-index"
15
15
  checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
16
16
 
17
- [[package]]
18
- name = "bitflags"
19
- version = "2.9.0"
20
- source = "registry+https://github.com/rust-lang/crates.io-index"
21
- checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
22
-
23
17
  [[package]]
24
18
  name = "cc"
25
- version = "1.2.19"
19
+ version = "1.2.24"
26
20
  source = "registry+https://github.com/rust-lang/crates.io-index"
27
- checksum = "8e3a13707ac958681c13b39b458c073d0d9bc8a22cb1b2f4c8e55eb72c13f362"
21
+ checksum = "16595d3be041c03b09d08d0858631facccee9221e579704070e6e9e4915d3bc7"
28
22
  dependencies = [
29
23
  "shlex",
30
24
  ]
31
25
 
32
26
  [[package]]
33
- name = "cfg-if"
34
- version = "1.0.0"
35
- source = "registry+https://github.com/rust-lang/crates.io-index"
36
- checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
37
-
38
- [[package]]
39
- name = "crossbeam-utils"
40
- version = "0.8.21"
27
+ name = "equivalent"
28
+ version = "1.0.2"
41
29
  source = "registry+https://github.com/rust-lang/crates.io-index"
42
- checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
43
-
44
- [[package]]
45
- name = "dashmap"
46
- version = "6.1.0"
47
- source = "registry+https://github.com/rust-lang/crates.io-index"
48
- checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf"
49
- dependencies = [
50
- "cfg-if",
51
- "crossbeam-utils",
52
- "hashbrown",
53
- "lock_api",
54
- "once_cell",
55
- "parking_lot_core",
56
- ]
57
-
58
- [[package]]
59
- name = "hashbrown"
60
- version = "0.14.5"
61
- source = "registry+https://github.com/rust-lang/crates.io-index"
62
- checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
30
+ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
63
31
 
64
32
  [[package]]
65
33
  name = "heck"
@@ -79,16 +47,6 @@ version = "0.2.172"
79
47
  source = "registry+https://github.com/rust-lang/crates.io-index"
80
48
  checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
81
49
 
82
- [[package]]
83
- name = "lock_api"
84
- version = "0.4.12"
85
- source = "registry+https://github.com/rust-lang/crates.io-index"
86
- checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
87
- dependencies = [
88
- "autocfg",
89
- "scopeguard",
90
- ]
91
-
92
50
  [[package]]
93
51
  name = "log"
94
52
  version = "0.4.27"
@@ -106,14 +64,14 @@ dependencies = [
106
64
 
107
65
  [[package]]
108
66
  name = "mio"
109
- version = "1.0.3"
67
+ version = "1.0.4"
110
68
  source = "registry+https://github.com/rust-lang/crates.io-index"
111
- checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
69
+ checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c"
112
70
  dependencies = [
113
71
  "libc",
114
72
  "log",
115
73
  "wasi",
116
- "windows-sys",
74
+ "windows-sys 0.59.0",
117
75
  ]
118
76
 
119
77
  [[package]]
@@ -123,16 +81,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
123
81
  checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
124
82
 
125
83
  [[package]]
126
- name = "parking_lot_core"
127
- version = "0.9.10"
84
+ name = "papaya"
85
+ version = "0.2.1"
128
86
  source = "registry+https://github.com/rust-lang/crates.io-index"
129
- checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
87
+ checksum = "6827e3fc394523c21d4464d02c0bb1c19966ea4a58a9844ad6d746214179d2bc"
130
88
  dependencies = [
131
- "cfg-if",
132
- "libc",
133
- "redox_syscall",
134
- "smallvec",
135
- "windows-targets",
89
+ "equivalent",
90
+ "seize",
136
91
  ]
137
92
 
138
93
  [[package]]
@@ -152,12 +107,11 @@ dependencies = [
152
107
 
153
108
  [[package]]
154
109
  name = "pyo3"
155
- version = "0.24.1"
110
+ version = "0.25.0"
156
111
  source = "registry+https://github.com/rust-lang/crates.io-index"
157
- checksum = "17da310086b068fbdcefbba30aeb3721d5bb9af8db4987d6735b2183ca567229"
112
+ checksum = "f239d656363bcee73afef85277f1b281e8ac6212a1d42aa90e55b90ed43c47a4"
158
113
  dependencies = [
159
114
  "anyhow",
160
- "cfg-if",
161
115
  "indoc",
162
116
  "libc",
163
117
  "memoffset",
@@ -171,9 +125,9 @@ dependencies = [
171
125
 
172
126
  [[package]]
173
127
  name = "pyo3-build-config"
174
- version = "0.24.1"
128
+ version = "0.25.0"
175
129
  source = "registry+https://github.com/rust-lang/crates.io-index"
176
- checksum = "e27165889bd793000a098bb966adc4300c312497ea25cf7a690a9f0ac5aa5fc1"
130
+ checksum = "755ea671a1c34044fa165247aaf6f419ca39caa6003aee791a0df2713d8f1b6d"
177
131
  dependencies = [
178
132
  "once_cell",
179
133
  "python3-dll-a",
@@ -182,9 +136,9 @@ dependencies = [
182
136
 
183
137
  [[package]]
184
138
  name = "pyo3-ffi"
185
- version = "0.24.1"
139
+ version = "0.25.0"
186
140
  source = "registry+https://github.com/rust-lang/crates.io-index"
187
- checksum = "05280526e1dbf6b420062f3ef228b78c0c54ba94e157f5cb724a609d0f2faabc"
141
+ checksum = "fc95a2e67091e44791d4ea300ff744be5293f394f1bafd9f78c080814d35956e"
188
142
  dependencies = [
189
143
  "libc",
190
144
  "pyo3-build-config",
@@ -192,9 +146,9 @@ dependencies = [
192
146
 
193
147
  [[package]]
194
148
  name = "pyo3-macros"
195
- version = "0.24.1"
149
+ version = "0.25.0"
196
150
  source = "registry+https://github.com/rust-lang/crates.io-index"
197
- checksum = "5c3ce5686aa4d3f63359a5100c62a127c9f15e8398e5fdeb5deef1fed5cd5f44"
151
+ checksum = "a179641d1b93920829a62f15e87c0ed791b6c8db2271ba0fd7c2686090510214"
198
152
  dependencies = [
199
153
  "proc-macro2",
200
154
  "pyo3-macros-backend",
@@ -204,9 +158,9 @@ dependencies = [
204
158
 
205
159
  [[package]]
206
160
  name = "pyo3-macros-backend"
207
- version = "0.24.1"
161
+ version = "0.25.0"
208
162
  source = "registry+https://github.com/rust-lang/crates.io-index"
209
- checksum = "f4cf6faa0cbfb0ed08e89beb8103ae9724eb4750e3a78084ba4017cbe94f3855"
163
+ checksum = "9dff85ebcaab8c441b0e3f7ae40a6963ecea8a9f5e74f647e33fcf5ec9a1e89e"
210
164
  dependencies = [
211
165
  "heck",
212
166
  "proc-macro2",
@@ -217,9 +171,9 @@ dependencies = [
217
171
 
218
172
  [[package]]
219
173
  name = "python3-dll-a"
220
- version = "0.2.13"
174
+ version = "0.2.14"
221
175
  source = "registry+https://github.com/rust-lang/crates.io-index"
222
- checksum = "49fe4227a288cf9493942ad0220ea3f185f4d1f2a14f197f7344d6d02f4ed4ed"
176
+ checksum = "d381ef313ae70b4da5f95f8a4de773c6aa5cd28f73adec4b4a31df70b66780d8"
223
177
  dependencies = [
224
178
  "cc",
225
179
  ]
@@ -233,33 +187,28 @@ dependencies = [
233
187
  "proc-macro2",
234
188
  ]
235
189
 
236
- [[package]]
237
- name = "redox_syscall"
238
- version = "0.5.11"
239
- source = "registry+https://github.com/rust-lang/crates.io-index"
240
- checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3"
241
- dependencies = [
242
- "bitflags",
243
- ]
244
-
245
190
  [[package]]
246
191
  name = "rloop"
247
- version = "0.1.1"
192
+ version = "0.1.3"
248
193
  dependencies = [
249
194
  "anyhow",
250
- "dashmap",
251
195
  "libc",
252
196
  "mio",
197
+ "papaya",
253
198
  "pyo3",
254
199
  "pyo3-build-config",
255
200
  "socket2",
256
201
  ]
257
202
 
258
203
  [[package]]
259
- name = "scopeguard"
260
- version = "1.2.0"
204
+ name = "seize"
205
+ version = "0.5.0"
261
206
  source = "registry+https://github.com/rust-lang/crates.io-index"
262
- checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
207
+ checksum = "e4b8d813387d566f627f3ea1b914c068aac94c40ae27ec43f5f33bde65abefe7"
208
+ dependencies = [
209
+ "libc",
210
+ "windows-sys 0.52.0",
211
+ ]
263
212
 
264
213
  [[package]]
265
214
  name = "shlex"
@@ -267,27 +216,21 @@ version = "1.3.0"
267
216
  source = "registry+https://github.com/rust-lang/crates.io-index"
268
217
  checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
269
218
 
270
- [[package]]
271
- name = "smallvec"
272
- version = "1.15.0"
273
- source = "registry+https://github.com/rust-lang/crates.io-index"
274
- checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9"
275
-
276
219
  [[package]]
277
220
  name = "socket2"
278
- version = "0.5.8"
221
+ version = "0.5.10"
279
222
  source = "registry+https://github.com/rust-lang/crates.io-index"
280
- checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8"
223
+ checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678"
281
224
  dependencies = [
282
225
  "libc",
283
- "windows-sys",
226
+ "windows-sys 0.52.0",
284
227
  ]
285
228
 
286
229
  [[package]]
287
230
  name = "syn"
288
- version = "2.0.100"
231
+ version = "2.0.101"
289
232
  source = "registry+https://github.com/rust-lang/crates.io-index"
290
- checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
233
+ checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
291
234
  dependencies = [
292
235
  "proc-macro2",
293
236
  "quote",
@@ -327,6 +270,15 @@ dependencies = [
327
270
  "windows-targets",
328
271
  ]
329
272
 
273
+ [[package]]
274
+ name = "windows-sys"
275
+ version = "0.59.0"
276
+ source = "registry+https://github.com/rust-lang/crates.io-index"
277
+ checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
278
+ dependencies = [
279
+ "windows-targets",
280
+ ]
281
+
330
282
  [[package]]
331
283
  name = "windows-targets"
332
284
  version = "0.52.6"
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "rloop"
3
- version = "0.1.1"
3
+ version = "0.1.3"
4
4
  description = "An asyncio event loop implemented in Rust"
5
5
  authors = ["Giovanni Barillari <g@baro.dev>"]
6
6
  license = "BSD-3-Clause"
@@ -31,16 +31,16 @@ crate-type = ["cdylib"]
31
31
 
32
32
  [dependencies]
33
33
  anyhow = "=1.0"
34
- dashmap = { version = "=6.1", features = ["inline"] }
35
34
  mio = { version = "=1.0", features = ["net", "os-ext", "os-poll"] }
36
- pyo3 = { version = "=0.24", features = ["anyhow", "extension-module", "generate-import-lib"] }
35
+ papaya = "=0.2"
36
+ pyo3 = { version = "=0.25", features = ["anyhow", "extension-module", "generate-import-lib"] }
37
37
  socket2 = { version = "=0.5", features = ["all"] }
38
38
 
39
39
  [target.'cfg(unix)'.dependencies]
40
40
  libc = "0.2.159"
41
41
 
42
42
  [build-dependencies]
43
- pyo3-build-config = "=0.24"
43
+ pyo3-build-config = "=0.25"
44
44
 
45
45
  [profile.release]
46
46
  codegen-units = 1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rloop
3
- Version: 0.1.1
3
+ Version: 0.1.3
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: BSD License
@@ -27,7 +27,7 @@ class Server:
27
27
  # raise RuntimeError(f'server {self!r} is closed')
28
28
 
29
29
  self._inner._start_serving()
30
- self._sff = self._loop.create_future()
30
+ self._sff = self._inner._loop.create_future()
31
31
 
32
32
  try:
33
33
  await self._sff
@@ -1,5 +1,5 @@
1
1
  use std::{
2
- collections::{BinaryHeap, HashSet, VecDeque},
2
+ collections::{BinaryHeap, VecDeque},
3
3
  io::Read,
4
4
  mem,
5
5
  os::fd::{AsRawFd, FromRawFd},
@@ -8,7 +8,6 @@ use std::{
8
8
  };
9
9
 
10
10
  use anyhow::Result;
11
- use dashmap::DashMap;
12
11
  use mio::{event, net::TcpListener, Interest, Poll, Token};
13
12
  use pyo3::prelude::*;
14
13
 
@@ -28,13 +27,12 @@ const WAKEB: &[u8; 1] = b"\0";
28
27
  enum IOHandle {
29
28
  Internal,
30
29
  Py(PyHandleData),
31
- Signals(Source),
30
+ Signals,
32
31
  TCPListener(TCPListenerHandleData),
33
- TCPStream(TCPStreamHandleData),
32
+ TCPStream(Interest),
34
33
  }
35
34
 
36
35
  struct PyHandleData {
37
- source: Source,
38
36
  interest: Interest,
39
37
  cbr: Option<Py<CBHandle>>,
40
38
  cbw: Option<Py<CBHandle>>,
@@ -45,11 +43,6 @@ struct TCPListenerHandleData {
45
43
  server: TCPServerRef,
46
44
  }
47
45
 
48
- struct TCPStreamHandleData {
49
- source: Source,
50
- interest: Interest,
51
- }
52
-
53
46
  pub(crate) struct EventLoopRunState {
54
47
  buf: Box<[u8]>,
55
48
  events: event::Events,
@@ -62,7 +55,7 @@ pub(crate) struct EventLoopRunState {
62
55
  pub struct EventLoop {
63
56
  idle: atomic::AtomicBool,
64
57
  io: Mutex<Poll>,
65
- handles_io: DashMap<Token, IOHandle>,
58
+ handles_io: papaya::HashMap<Token, IOHandle>,
66
59
  handles_ready: Mutex<VecDeque<BoxedHandle>>,
67
60
  handles_sched: Mutex<BinaryHeap<Timer>>,
68
61
  epoch: Instant,
@@ -74,7 +67,7 @@ pub struct EventLoop {
74
67
  exc_handler: RwLock<PyObject>,
75
68
  exception_handler: RwLock<PyObject>,
76
69
  executor: RwLock<PyObject>,
77
- sig_handlers: DashMap<u8, Py<CBHandle>>,
70
+ sig_handlers: papaya::HashMap<u8, Py<CBHandle>>,
78
71
  sig_listening: atomic::AtomicBool,
79
72
  sig_loop_handled: atomic::AtomicBool,
80
73
  sig_wfd: RwLock<PyObject>,
@@ -84,8 +77,8 @@ pub struct EventLoop {
84
77
  ssock_r: RwLock<PyObject>,
85
78
  ssock_w: RwLock<PyObject>,
86
79
  task_factory: RwLock<PyObject>,
87
- tcp_lstreams: DashMap<usize, HashSet<usize>>,
88
- tcp_transports: DashMap<usize, Py<TCPTransport>>,
80
+ tcp_lstreams: papaya::HashMap<usize, papaya::HashSet<usize>>,
81
+ tcp_transports: papaya::HashMap<usize, Py<TCPTransport>>,
89
82
  thread_id: atomic::AtomicI64,
90
83
  watcher_child: RwLock<PyObject>,
91
84
  #[pyo3(get)]
@@ -106,7 +99,7 @@ impl EventLoop {
106
99
  let guard = self.io.lock().unwrap();
107
100
  guard.registry().register(&mut source, token, Interest::READABLE)?;
108
101
  }
109
- self.handles_io.insert(token, IOHandle::Internal);
102
+ self.handles_io.pin().insert(token, IOHandle::Internal);
110
103
  {
111
104
  let mut guard = self.wsock.lock().unwrap();
112
105
  self.wsock_fd.store(sock_w.as_raw_fd(), atomic::Ordering::Relaxed);
@@ -132,7 +125,7 @@ impl EventLoop {
132
125
  let guard = self.io.lock().unwrap();
133
126
  _ = guard.registry().deregister(&mut source);
134
127
  }
135
- self.handles_io.remove(&token);
128
+ self.handles_io.pin().remove(&token);
136
129
  }
137
130
 
138
131
  #[inline]
@@ -197,15 +190,18 @@ impl EventLoop {
197
190
  self.counter_ready
198
191
  .fetch_sub(cb_handles.len(), atomic::Ordering::Release);
199
192
 
200
- for event in &state.events {
201
- // NOTE: cancellation is not necessary as we have custom futures
202
- if let Some(io_handle) = self.handles_io.get(&event.token()) {
203
- match io_handle.value() {
204
- IOHandle::Py(handle) => self.handle_io_py(py, event, handle, &mut cb_handles),
205
- IOHandle::TCPListener(handle) => self.handle_io_tcpl(py, handle, &mut cb_handles),
206
- IOHandle::TCPStream(_) => self.handle_io_tcps(event, &mut cb_handles),
207
- IOHandle::Internal => self.handle_io_internal(&mut state.sock, &mut state.buf),
208
- IOHandle::Signals(_) => self.handle_io_signals(py, &mut state.buf, &mut cb_handles),
193
+ {
194
+ let io_handles = self.handles_io.pin();
195
+ for event in &state.events {
196
+ // NOTE: cancellation is not necessary as we have custom futures
197
+ if let Some(io_handle) = io_handles.get(&event.token()) {
198
+ match io_handle {
199
+ IOHandle::Py(handle) => self.handle_io_py(py, event, handle, &mut cb_handles),
200
+ IOHandle::TCPListener(handle) => self.handle_io_tcpl(py, handle, &io_handles, &mut cb_handles),
201
+ IOHandle::TCPStream(_) => self.handle_io_tcps(event, &mut cb_handles),
202
+ IOHandle::Internal => self.handle_io_internal(&mut state.sock, &mut state.buf),
203
+ IOHandle::Signals => self.handle_io_signals(py, &mut state.buf, &mut cb_handles),
204
+ }
209
205
  }
210
206
  }
211
207
  }
@@ -275,23 +271,33 @@ impl EventLoop {
275
271
  }
276
272
 
277
273
  #[inline]
278
- fn handle_io_tcpl(&self, py: Python, handle: &TCPListenerHandleData, handles: &mut VecDeque<BoxedHandle>) {
279
- match &handle.source {
280
- Source::TCPListener(listener) => {
281
- while let Ok((stream, _)) = listener.accept() {
282
- let fd = stream.as_raw_fd() as usize;
283
- let (pytransport, stream_handle) = handle.server.new_stream(py, stream);
284
- self.tcp_transports.insert(fd, pytransport);
285
- self.tcp_lstreams.alter(&handle.server.fd, |_, mut v| {
286
- v.insert(fd);
287
- v
288
- });
289
- self.tcp_stream_add(fd, Interest::READABLE);
290
- handles.push_back(stream_handle);
291
- }
274
+ fn handle_io_tcpl(
275
+ &self,
276
+ py: Python,
277
+ handle: &TCPListenerHandleData,
278
+ io_handles: &papaya::HashMapRef<'_, Token, IOHandle, std::hash::RandomState, papaya::LocalGuard<'_>>,
279
+ handles: &mut VecDeque<BoxedHandle>,
280
+ ) {
281
+ if let Source::TCPListener(listener) = &handle.source {
282
+ let guard_poll = self.io.lock().unwrap();
283
+ let transports = self.tcp_transports.pin();
284
+ let streams = self.tcp_lstreams.pin();
285
+ let lstreams = streams.get(&handle.server.fd).unwrap().pin();
286
+ while let Ok((stream, _)) = listener.accept() {
287
+ let fd = stream.as_raw_fd() as usize;
288
+ let token = Token(fd);
289
+ #[allow(clippy::cast_possible_wrap)]
290
+ let mut source = Source::TCPStream(fd as i32);
291
+ let (pytransport, stream_handle) = handle.server.new_stream(py, stream);
292
+ transports.insert(fd, pytransport);
293
+ lstreams.insert(fd);
294
+ _ = guard_poll.registry().register(&mut source, token, Interest::READABLE);
295
+ io_handles.insert(Token(fd), IOHandle::TCPStream(Interest::READABLE));
296
+ handles.push_back(stream_handle);
292
297
  }
293
- _ => unreachable!(),
298
+ return;
294
299
  }
300
+ unreachable!()
295
301
  }
296
302
 
297
303
  #[inline]
@@ -319,9 +325,8 @@ impl EventLoop {
319
325
 
320
326
  #[inline]
321
327
  fn sig_handle(&self, py: Python, sig: u8, handles_ready: &mut VecDeque<BoxedHandle>) {
322
- if let Some(handle) = self.sig_handlers.get(&sig) {
328
+ if let Some(handle) = self.sig_handlers.pin().get(&sig) {
323
329
  self.sig_loop_handled.store(true, atomic::Ordering::Relaxed);
324
- let handle = handle.value();
325
330
 
326
331
  if handle.cancelled() {
327
332
  self._sig_rem(sig);
@@ -343,112 +348,114 @@ impl EventLoop {
343
348
  let mut source = Source::TCPListener(listener);
344
349
  let guard_poll = self.io.lock().unwrap();
345
350
  let _ = guard_poll.registry().register(&mut source, token, Interest::READABLE);
346
- self.tcp_lstreams.insert(fd, HashSet::new());
351
+ self.tcp_lstreams.pin().insert(fd, papaya::HashSet::new());
347
352
  self.handles_io
353
+ .pin()
348
354
  .insert(token, IOHandle::TCPListener(TCPListenerHandleData { source, server }));
349
355
  }
350
356
 
351
357
  pub(crate) fn tcp_listener_rem(&self, fd: usize) -> Result<bool> {
352
358
  let token = Token(fd);
353
- if let Some((_, handle)) = self.handles_io.remove(&token) {
354
- match handle {
355
- IOHandle::TCPListener(mut item) => {
356
- self.tcp_lstreams.remove(&fd);
357
- let guard_poll = self.io.lock().unwrap();
358
- guard_poll.registry().deregister(&mut item.source)?;
359
- return Ok(true);
360
- }
361
- _ => unreachable!(),
359
+ if let Some(handle) = self.handles_io.pin().remove(&token) {
360
+ if let IOHandle::TCPListener(_) = handle {
361
+ self.tcp_lstreams.pin().remove(&fd);
362
+ #[allow(clippy::cast_possible_wrap)]
363
+ let mut source = Source::FD(fd as i32);
364
+ let guard_poll = self.io.lock().unwrap();
365
+ guard_poll.registry().deregister(&mut source)?;
366
+ return Ok(true);
362
367
  }
368
+ unreachable!()
363
369
  }
364
370
  Ok(false)
365
371
  }
366
372
 
367
373
  pub(crate) fn tcp_stream_add(&self, fd: usize, interest: Interest) {
368
374
  let token = Token(fd);
369
- self.handles_io
370
- .entry(token)
371
- .and_modify(|io_handle| match io_handle {
372
- IOHandle::TCPStream(data) => {
373
- if data.interest == interest {
374
- return;
375
+ self.handles_io.pin().update_or_insert_with(
376
+ token,
377
+ |io_handle| {
378
+ if let IOHandle::TCPStream(interest_prev) = io_handle {
379
+ if *interest_prev == interest {
380
+ return IOHandle::TCPStream(interest);
375
381
  }
376
382
 
377
- let interests = data.interest | interest;
383
+ let interests = *interest_prev | interest;
378
384
  {
385
+ #[allow(clippy::cast_possible_wrap)]
386
+ let mut source = Source::FD(fd as i32);
379
387
  let guard_poll = self.io.lock().unwrap();
380
- _ = guard_poll.registry().reregister(&mut data.source, token, interests);
388
+ _ = guard_poll.registry().reregister(&mut source, token, interests);
381
389
  }
382
- data.interest = interests;
390
+ return IOHandle::TCPStream(interests);
383
391
  }
384
- _ => unreachable!(),
385
- })
386
- .or_insert_with(|| {
392
+ unreachable!()
393
+ },
394
+ || {
387
395
  #[allow(clippy::cast_possible_wrap)]
388
396
  let mut source = Source::TCPStream(fd as i32);
389
397
  {
390
398
  let guard_poll = self.io.lock().unwrap();
391
399
  _ = guard_poll.registry().register(&mut source, token, interest);
392
400
  }
393
- IOHandle::TCPStream(TCPStreamHandleData { source, interest })
394
- });
401
+ IOHandle::TCPStream(interest)
402
+ },
403
+ );
395
404
  }
396
405
 
397
406
  pub(crate) fn tcp_stream_rem(&self, fd: usize, interest: Interest) {
398
407
  let token = Token(fd);
399
408
 
400
- if let Some((_, io_handle)) = self.handles_io.remove_if(&token, |_, io_handle| {
401
- if let IOHandle::TCPStream(handle) = io_handle {
402
- return handle.interest == interest;
409
+ match self.handles_io.pin().remove_if(&token, |_, io_handle| {
410
+ if let IOHandle::TCPStream(interest_ex) = io_handle {
411
+ return *interest_ex == interest;
403
412
  }
404
413
  false
405
414
  }) {
406
- match io_handle {
407
- IOHandle::TCPStream(mut handle) => {
408
- let guard_poll = self.io.lock().unwrap();
409
- _ = guard_poll.registry().deregister(&mut handle.source);
410
- }
411
- _ => unreachable!(),
412
- }
413
- return;
414
- }
415
-
416
- self.handles_io.alter(&token, |_, mut io_handle| {
417
- if let IOHandle::TCPStream(handle) = &mut io_handle {
418
- handle.interest = handle.interest.remove(interest).unwrap();
415
+ Ok(None) => {}
416
+ Ok(_) => {
417
+ #[allow(clippy::cast_possible_wrap)]
418
+ let mut source = Source::FD(fd as i32);
419
419
  let guard_poll = self.io.lock().unwrap();
420
- _ = guard_poll
421
- .registry()
422
- .reregister(&mut handle.source, token, handle.interest);
420
+ _ = guard_poll.registry().deregister(&mut source);
421
+ }
422
+ _ => {
423
+ self.handles_io.pin().update(token, |io_handle| {
424
+ if let IOHandle::TCPStream(interest_ex) = io_handle {
425
+ let interest_new = interest_ex.remove(interest).unwrap();
426
+ #[allow(clippy::cast_possible_wrap)]
427
+ let mut source = Source::FD(fd as i32);
428
+ let guard_poll = self.io.lock().unwrap();
429
+ _ = guard_poll.registry().reregister(&mut source, token, interest_new);
430
+ return IOHandle::TCPStream(interest_new);
431
+ }
432
+ unreachable!()
433
+ });
423
434
  }
424
- io_handle
425
- });
435
+ }
426
436
  }
427
437
 
428
438
  #[inline(always)]
429
439
  pub(crate) fn tcp_stream_close(&self, py: Python, fd: usize) {
430
- if let Some((_, transport)) = self.tcp_transports.remove(&fd) {
440
+ if let Some(transport) = self.tcp_transports.pin().remove(&fd) {
431
441
  if let Some(lfd) = transport.borrow(py).lfd {
432
- self.tcp_lstreams.alter(&lfd, |_, mut v| {
433
- v.remove(&fd);
434
- v
435
- });
442
+ self.tcp_lstreams.pin().get(&lfd).map(|v| v.pin().remove(&fd));
436
443
  }
437
- transport.drop_ref(py);
444
+ // transport.drop_ref(py);
438
445
  }
439
446
  }
440
447
 
441
448
  #[inline(always)]
442
449
  pub(crate) fn get_tcp_transport(&self, fd: usize, py: Python) -> Py<TCPTransport> {
443
- self.tcp_transports.get(&fd).unwrap().clone_ref(py)
450
+ self.tcp_transports.pin().get(&fd).unwrap().clone_ref(py)
444
451
  }
445
452
 
446
453
  pub(crate) fn with_tcp_listener_streams<T>(&self, fd: usize, func: T)
447
454
  where
448
- T: FnOnce(&HashSet<usize>),
455
+ T: FnOnce(&papaya::HashSet<usize>),
449
456
  {
450
- if let Some(streams_ref) = self.tcp_lstreams.get(&fd) {
451
- func(streams_ref.value());
457
+ if let Some(streams_ref) = self.tcp_lstreams.pin().get(&fd) {
458
+ func(streams_ref);
452
459
  }
453
460
  }
454
461
 
@@ -633,7 +640,7 @@ impl EventLoop {
633
640
  Ok(Self {
634
641
  idle: atomic::AtomicBool::new(false),
635
642
  io: Mutex::new(Poll::new()?),
636
- handles_io: DashMap::with_capacity(128),
643
+ handles_io: papaya::HashMap::with_capacity(128),
637
644
  handles_ready: Mutex::new(VecDeque::with_capacity(128)),
638
645
  handles_sched: Mutex::new(BinaryHeap::with_capacity(32)),
639
646
  epoch: Instant::now(),
@@ -645,7 +652,7 @@ impl EventLoop {
645
652
  exc_handler: RwLock::new(py.None()),
646
653
  exception_handler: RwLock::new(py.None()),
647
654
  executor: RwLock::new(py.None()),
648
- sig_handlers: DashMap::with_capacity(32),
655
+ sig_handlers: papaya::HashMap::with_capacity(32),
649
656
  sig_listening: atomic::AtomicBool::new(false),
650
657
  sig_loop_handled: atomic::AtomicBool::new(false),
651
658
  sig_wfd: RwLock::new(py.None()),
@@ -655,8 +662,8 @@ impl EventLoop {
655
662
  ssock_r: RwLock::new(py.None()),
656
663
  ssock_w: RwLock::new(py.None()),
657
664
  task_factory: RwLock::new(py.None()),
658
- tcp_lstreams: DashMap::with_capacity(32),
659
- tcp_transports: DashMap::with_capacity(1024),
665
+ tcp_lstreams: papaya::HashMap::with_capacity(32),
666
+ tcp_transports: papaya::HashMap::with_capacity(1024),
660
667
  thread_id: atomic::AtomicI64::new(0),
661
668
  watcher_child: RwLock::new(py.None()),
662
669
  _asyncgens: weakset(py)?.unbind(),
@@ -838,14 +845,16 @@ impl EventLoop {
838
845
  let guard_poll = self.io.lock().unwrap();
839
846
  guard_poll.registry().register(&mut source, token, interest)?;
840
847
  }
841
- self.handles_io.insert(token, IOHandle::Signals(source));
848
+ self.handles_io.pin().insert(token, IOHandle::Signals);
842
849
 
843
850
  Ok(())
844
851
  }
845
852
 
846
853
  fn _ssock_del(&self, fd_r: usize) -> PyResult<()> {
847
854
  let token = Token(fd_r);
848
- if let Some((_, IOHandle::Signals(mut source))) = self.handles_io.remove(&token) {
855
+ if let Some(IOHandle::Signals) = self.handles_io.pin().remove(&token) {
856
+ #[allow(clippy::cast_possible_wrap)]
857
+ let mut source = Source::FD(fd_r as i32);
849
858
  let guard_poll = self.io.lock().unwrap();
850
859
  guard_poll.registry().deregister(&mut source)?;
851
860
  }
@@ -937,18 +946,24 @@ impl EventLoop {
937
946
  )
938
947
  .unwrap();
939
948
 
940
- self.handles_io
941
- .entry(token)
942
- .and_modify(|io_handle| match io_handle {
943
- IOHandle::Py(data) => {
944
- data.interest |= Interest::READABLE;
945
- data.cbr = Some(handle.clone_ref(py));
949
+ self.handles_io.pin().update_or_insert_with(
950
+ token,
951
+ |io_handle| {
952
+ if let IOHandle::Py(data) = io_handle {
953
+ let interest = data.interest | Interest::READABLE;
954
+ #[allow(clippy::cast_possible_wrap)]
955
+ let mut source = Source::FD(fd as i32);
946
956
  let guard_poll = self.io.lock().unwrap();
947
- _ = guard_poll.registry().reregister(&mut data.source, token, data.interest);
957
+ _ = guard_poll.registry().reregister(&mut source, token, data.interest);
958
+ return IOHandle::Py(PyHandleData {
959
+ interest,
960
+ cbr: Some(handle.clone_ref(py)),
961
+ cbw: Some(data.cbw.as_ref().unwrap().clone_ref(py)),
962
+ });
948
963
  }
949
- _ => unreachable!(),
950
- })
951
- .or_insert_with(|| {
964
+ unreachable!()
965
+ },
966
+ || {
952
967
  #[allow(clippy::cast_possible_wrap)]
953
968
  let mut source = Source::FD(fd as i32);
954
969
  let interest = Interest::READABLE;
@@ -957,50 +972,52 @@ impl EventLoop {
957
972
  _ = guard_poll.registry().register(&mut source, token, interest);
958
973
  }
959
974
  IOHandle::Py(PyHandleData {
960
- source,
961
975
  interest,
962
976
  cbr: Some(handle.clone_ref(py)),
963
977
  cbw: None,
964
978
  })
965
- });
979
+ },
980
+ );
966
981
 
967
982
  handle
968
983
  }
969
984
 
970
- fn remove_reader(&self, fd: usize) -> bool {
985
+ fn remove_reader(&self, py: Python, fd: usize) -> bool {
971
986
  let token = Token(fd);
972
987
 
973
- if let Some((_, io_handle)) = self.handles_io.remove_if(&token, |_, io_handle| {
974
- if let IOHandle::Py(handle) = io_handle {
975
- return handle.interest == Interest::READABLE;
988
+ match self.handles_io.pin().remove_if(&token, |_, io_handle| {
989
+ if let IOHandle::Py(data) = io_handle {
990
+ return data.interest == Interest::READABLE;
976
991
  }
977
992
  false
978
993
  }) {
979
- match io_handle {
980
- IOHandle::Py(mut handle) => {
981
- let guard_poll = self.io.lock().unwrap();
982
- _ = guard_poll.registry().deregister(&mut handle.source);
983
- }
984
- _ => unreachable!(),
985
- }
986
- return true;
987
- }
988
-
989
- let mut altered = false;
990
- self.handles_io.alter(&token, |_, mut io_handle| {
991
- if let IOHandle::Py(handle) = &mut io_handle {
992
- handle.interest = Interest::WRITABLE;
993
- handle.cbr = None;
994
+ Ok(None) => false,
995
+ Ok(_) => {
996
+ #[allow(clippy::cast_possible_wrap)]
997
+ let mut source = Source::FD(fd as i32);
994
998
  let guard_poll = self.io.lock().unwrap();
995
- _ = guard_poll
996
- .registry()
997
- .reregister(&mut handle.source, token, handle.interest);
998
- altered = true;
999
+ _ = guard_poll.registry().deregister(&mut source);
1000
+ true
999
1001
  }
1000
- io_handle
1001
- });
1002
-
1003
- altered
1002
+ _ => {
1003
+ self.handles_io.pin().update(token, |io_handle| {
1004
+ if let IOHandle::Py(data) = io_handle {
1005
+ let interest = Interest::WRITABLE;
1006
+ #[allow(clippy::cast_possible_wrap)]
1007
+ let mut source = Source::FD(fd as i32);
1008
+ let guard_poll = self.io.lock().unwrap();
1009
+ _ = guard_poll.registry().reregister(&mut source, token, interest);
1010
+ return IOHandle::Py(PyHandleData {
1011
+ interest,
1012
+ cbr: None,
1013
+ cbw: Some(data.cbw.as_ref().unwrap().clone_ref(py)),
1014
+ });
1015
+ }
1016
+ unreachable!()
1017
+ });
1018
+ true
1019
+ }
1020
+ }
1004
1021
  }
1005
1022
 
1006
1023
  #[pyo3(signature = (fd, callback, *args, context=None))]
@@ -1019,18 +1036,24 @@ impl EventLoop {
1019
1036
  )
1020
1037
  .unwrap();
1021
1038
 
1022
- self.handles_io
1023
- .entry(token)
1024
- .and_modify(|io_handle| match io_handle {
1025
- IOHandle::Py(data) => {
1026
- data.interest |= Interest::WRITABLE;
1027
- data.cbw = Some(handle.clone_ref(py));
1039
+ self.handles_io.pin().update_or_insert_with(
1040
+ token,
1041
+ |io_handle| {
1042
+ if let IOHandle::Py(data) = io_handle {
1043
+ let interest = data.interest | Interest::WRITABLE;
1044
+ #[allow(clippy::cast_possible_wrap)]
1045
+ let mut source = Source::FD(fd as i32);
1028
1046
  let guard_poll = self.io.lock().unwrap();
1029
- _ = guard_poll.registry().reregister(&mut data.source, token, data.interest);
1047
+ _ = guard_poll.registry().reregister(&mut source, token, data.interest);
1048
+ return IOHandle::Py(PyHandleData {
1049
+ interest,
1050
+ cbr: Some(data.cbr.as_ref().unwrap().clone_ref(py)),
1051
+ cbw: Some(handle.clone_ref(py)),
1052
+ });
1030
1053
  }
1031
- _ => unreachable!(),
1032
- })
1033
- .or_insert_with(|| {
1054
+ unreachable!()
1055
+ },
1056
+ || {
1034
1057
  #[allow(clippy::cast_possible_wrap)]
1035
1058
  let mut source = Source::FD(fd as i32);
1036
1059
  let interest = Interest::WRITABLE;
@@ -1039,50 +1062,52 @@ impl EventLoop {
1039
1062
  _ = guard_poll.registry().register(&mut source, token, interest);
1040
1063
  }
1041
1064
  IOHandle::Py(PyHandleData {
1042
- source,
1043
1065
  interest,
1044
1066
  cbr: None,
1045
1067
  cbw: Some(handle.clone_ref(py)),
1046
1068
  })
1047
- });
1069
+ },
1070
+ );
1048
1071
 
1049
1072
  handle
1050
1073
  }
1051
1074
 
1052
- fn remove_writer(&self, fd: usize) -> bool {
1075
+ fn remove_writer(&self, py: Python, fd: usize) -> bool {
1053
1076
  let token = Token(fd);
1054
1077
 
1055
- if let Some((_, io_handle)) = self.handles_io.remove_if(&token, |_, io_handle| {
1056
- if let IOHandle::Py(handle) = io_handle {
1057
- return handle.interest == Interest::WRITABLE;
1078
+ match self.handles_io.pin().remove_if(&token, |_, io_handle| {
1079
+ if let IOHandle::Py(data) = io_handle {
1080
+ return data.interest == Interest::WRITABLE;
1058
1081
  }
1059
1082
  false
1060
1083
  }) {
1061
- match io_handle {
1062
- IOHandle::Py(mut handle) => {
1063
- let guard_poll = self.io.lock().unwrap();
1064
- _ = guard_poll.registry().deregister(&mut handle.source);
1065
- }
1066
- _ => unreachable!(),
1067
- }
1068
- return true;
1069
- }
1070
-
1071
- let mut altered = false;
1072
- self.handles_io.alter(&token, |_, mut io_handle| {
1073
- if let IOHandle::Py(handle) = &mut io_handle {
1074
- handle.interest = Interest::READABLE;
1075
- handle.cbw = None;
1084
+ Ok(None) => false,
1085
+ Ok(_) => {
1086
+ #[allow(clippy::cast_possible_wrap)]
1087
+ let mut source = Source::FD(fd as i32);
1076
1088
  let guard_poll = self.io.lock().unwrap();
1077
- _ = guard_poll
1078
- .registry()
1079
- .reregister(&mut handle.source, token, handle.interest);
1080
- altered = true;
1089
+ _ = guard_poll.registry().deregister(&mut source);
1090
+ true
1081
1091
  }
1082
- io_handle
1083
- });
1084
-
1085
- altered
1092
+ _ => {
1093
+ self.handles_io.pin().update(token, |io_handle| {
1094
+ if let IOHandle::Py(data) = io_handle {
1095
+ let interest = Interest::READABLE;
1096
+ #[allow(clippy::cast_possible_wrap)]
1097
+ let mut source = Source::FD(fd as i32);
1098
+ let guard_poll = self.io.lock().unwrap();
1099
+ _ = guard_poll.registry().reregister(&mut source, token, interest);
1100
+ return IOHandle::Py(PyHandleData {
1101
+ interest,
1102
+ cbr: Some(data.cbr.as_ref().unwrap().clone_ref(py)),
1103
+ cbw: None,
1104
+ });
1105
+ }
1106
+ unreachable!()
1107
+ });
1108
+ true
1109
+ }
1110
+ }
1086
1111
  }
1087
1112
 
1088
1113
  fn _tcp_conn(
@@ -1096,7 +1121,7 @@ impl EventLoop {
1096
1121
  let fd = transport.fd;
1097
1122
  let pytransport = Py::new(py, transport)?;
1098
1123
  let proto = TCPTransport::attach(&pytransport, py)?;
1099
- rself.tcp_transports.insert(fd, pytransport.clone_ref(py));
1124
+ rself.tcp_transports.pin().insert(fd, pytransport.clone_ref(py));
1100
1125
  rself.tcp_stream_add(fd, Interest::READABLE);
1101
1126
  Ok((pytransport, proto))
1102
1127
  }
@@ -1118,20 +1143,20 @@ impl EventLoop {
1118
1143
  }
1119
1144
 
1120
1145
  fn _tcp_stream_bound(&self, fd: usize) -> bool {
1121
- self.tcp_transports.contains_key(&fd)
1146
+ self.tcp_transports.pin().contains_key(&fd)
1122
1147
  }
1123
1148
 
1124
1149
  fn _sig_add(&self, py: Python, sig: u8, callback: PyObject, args: PyObject, context: PyObject) {
1125
1150
  let handle = Py::new(py, CBHandle::new(callback, args, context)).unwrap();
1126
- self.sig_handlers.insert(sig, handle);
1151
+ self.sig_handlers.pin().insert(sig, handle);
1127
1152
  }
1128
1153
 
1129
1154
  fn _sig_rem(&self, sig: u8) -> bool {
1130
- self.sig_handlers.remove(&sig).is_some()
1155
+ self.sig_handlers.pin().remove(&sig).is_some()
1131
1156
  }
1132
1157
 
1133
1158
  fn _sig_clear(&self) {
1134
- self.sig_handlers.clear();
1159
+ self.sig_handlers.pin().clear();
1135
1160
  }
1136
1161
 
1137
1162
  fn _run(&self, py: Python) -> PyResult<()> {
@@ -68,7 +68,7 @@ impl TCPServer {
68
68
  pub(crate) fn streams_close(&self, py: Python, event_loop: &EventLoop) {
69
69
  let mut transports = Vec::new();
70
70
  event_loop.with_tcp_listener_streams(self.fd as usize, |streams| {
71
- for stream_fd in streams {
71
+ for stream_fd in &streams.pin() {
72
72
  transports.push(event_loop.get_tcp_transport(*stream_fd, py));
73
73
  }
74
74
  });
@@ -80,7 +80,7 @@ impl TCPServer {
80
80
  pub(crate) fn streams_abort(&self, py: Python, event_loop: &EventLoop) {
81
81
  let mut transports = Vec::new();
82
82
  event_loop.with_tcp_listener_streams(self.fd as usize, |streams| {
83
- for stream_fd in streams {
83
+ for stream_fd in &streams.pin() {
84
84
  transports.push(event_loop.get_tcp_transport(*stream_fd, py));
85
85
  }
86
86
  });
@@ -264,6 +264,7 @@ impl TCPTransport {
264
264
  if self.closing.load(atomic::Ordering::Relaxed) {
265
265
  _ = self.protom_conn_lost.call1(
266
266
  py,
267
+ #[allow(clippy::obfuscated_if_else)]
267
268
  (errored
268
269
  .then(|| {
269
270
  pyo3::exceptions::PyRuntimeError::new_err("socket transport failed")
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