rloop 0.1.0a2__tar.gz → 0.1.0a3__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.
- {rloop-0.1.0a2 → rloop-0.1.0a3}/Cargo.lock +36 -84
- {rloop-0.1.0a2 → rloop-0.1.0a3}/Cargo.toml +1 -7
- {rloop-0.1.0a2 → rloop-0.1.0a3}/PKG-INFO +2 -2
- {rloop-0.1.0a2 → rloop-0.1.0a3}/pyproject.toml +3 -0
- {rloop-0.1.0a2 → rloop-0.1.0a3}/rloop/_rloop.pyi +2 -4
- {rloop-0.1.0a2 → rloop-0.1.0a3}/rloop/loop.py +30 -57
- {rloop-0.1.0a2 → rloop-0.1.0a3}/rloop/utils.py +1 -1
- {rloop-0.1.0a2 → rloop-0.1.0a3}/src/event_loop.rs +233 -133
- {rloop-0.1.0a2 → rloop-0.1.0a3}/src/handles.rs +2 -1
- {rloop-0.1.0a2 → rloop-0.1.0a3}/src/io.rs +4 -0
- {rloop-0.1.0a2 → rloop-0.1.0a3}/src/lib.rs +0 -8
- {rloop-0.1.0a2 → rloop-0.1.0a3}/LICENSE +0 -0
- {rloop-0.1.0a2 → rloop-0.1.0a3}/README.md +0 -0
- {rloop-0.1.0a2 → rloop-0.1.0a3}/rloop/__init__.py +0 -0
- {rloop-0.1.0a2 → rloop-0.1.0a3}/rloop/_compat.py +0 -0
- {rloop-0.1.0a2 → rloop-0.1.0a3}/rloop/exc.py +0 -0
- {rloop-0.1.0a2 → rloop-0.1.0a3}/rloop/futures.py +0 -0
- {rloop-0.1.0a2 → rloop-0.1.0a3}/rloop/subprocess.py +0 -0
- {rloop-0.1.0a2 → rloop-0.1.0a3}/rloop/transports.py +0 -0
- {rloop-0.1.0a2 → rloop-0.1.0a3}/src/py.rs +0 -0
- {rloop-0.1.0a2 → rloop-0.1.0a3}/tests/conftest.py +0 -0
- {rloop-0.1.0a2 → rloop-0.1.0a3}/tests/test_sockets.py +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# This file is automatically @generated by Cargo.
|
|
2
2
|
# It is not intended for manual editing.
|
|
3
|
-
version =
|
|
3
|
+
version = 4
|
|
4
4
|
|
|
5
5
|
[[package]]
|
|
6
6
|
name = "anyhow"
|
|
7
|
-
version = "1.0.
|
|
7
|
+
version = "1.0.94"
|
|
8
8
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
9
|
-
checksum = "
|
|
9
|
+
checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7"
|
|
10
10
|
|
|
11
11
|
[[package]]
|
|
12
12
|
name = "autocfg"
|
|
@@ -22,9 +22,9 @@ checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
|
|
22
22
|
|
|
23
23
|
[[package]]
|
|
24
24
|
name = "cc"
|
|
25
|
-
version = "1.
|
|
25
|
+
version = "1.2.5"
|
|
26
26
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
27
|
-
checksum = "
|
|
27
|
+
checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e"
|
|
28
28
|
dependencies = [
|
|
29
29
|
"shlex",
|
|
30
30
|
]
|
|
@@ -37,9 +37,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|
|
37
37
|
|
|
38
38
|
[[package]]
|
|
39
39
|
name = "crossbeam-utils"
|
|
40
|
-
version = "0.8.
|
|
40
|
+
version = "0.8.21"
|
|
41
41
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
42
|
-
checksum = "
|
|
42
|
+
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
|
43
43
|
|
|
44
44
|
[[package]]
|
|
45
45
|
name = "dashmap"
|
|
@@ -67,12 +67,6 @@ version = "0.5.0"
|
|
|
67
67
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
68
68
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
|
69
69
|
|
|
70
|
-
[[package]]
|
|
71
|
-
name = "hermit-abi"
|
|
72
|
-
version = "0.3.9"
|
|
73
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
74
|
-
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
|
|
75
|
-
|
|
76
70
|
[[package]]
|
|
77
71
|
name = "indoc"
|
|
78
72
|
version = "2.0.5"
|
|
@@ -81,19 +75,9 @@ checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5"
|
|
|
81
75
|
|
|
82
76
|
[[package]]
|
|
83
77
|
name = "libc"
|
|
84
|
-
version = "0.2.
|
|
78
|
+
version = "0.2.169"
|
|
85
79
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
86
|
-
checksum = "
|
|
87
|
-
|
|
88
|
-
[[package]]
|
|
89
|
-
name = "libmimalloc-sys"
|
|
90
|
-
version = "0.1.39"
|
|
91
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
92
|
-
checksum = "23aa6811d3bd4deb8a84dde645f943476d13b248d818edcf8ce0b2f37f036b44"
|
|
93
|
-
dependencies = [
|
|
94
|
-
"cc",
|
|
95
|
-
"libc",
|
|
96
|
-
]
|
|
80
|
+
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
|
|
97
81
|
|
|
98
82
|
[[package]]
|
|
99
83
|
name = "lock_api"
|
|
@@ -120,22 +104,12 @@ dependencies = [
|
|
|
120
104
|
"autocfg",
|
|
121
105
|
]
|
|
122
106
|
|
|
123
|
-
[[package]]
|
|
124
|
-
name = "mimalloc"
|
|
125
|
-
version = "0.1.43"
|
|
126
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
127
|
-
checksum = "68914350ae34959d83f732418d51e2427a794055d0b9529f48259ac07af65633"
|
|
128
|
-
dependencies = [
|
|
129
|
-
"libmimalloc-sys",
|
|
130
|
-
]
|
|
131
|
-
|
|
132
107
|
[[package]]
|
|
133
108
|
name = "mio"
|
|
134
|
-
version = "1.0.
|
|
109
|
+
version = "1.0.3"
|
|
135
110
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
136
|
-
checksum = "
|
|
111
|
+
checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
|
|
137
112
|
dependencies = [
|
|
138
|
-
"hermit-abi",
|
|
139
113
|
"libc",
|
|
140
114
|
"log",
|
|
141
115
|
"wasi",
|
|
@@ -163,24 +137,24 @@ dependencies = [
|
|
|
163
137
|
|
|
164
138
|
[[package]]
|
|
165
139
|
name = "portable-atomic"
|
|
166
|
-
version = "1.
|
|
140
|
+
version = "1.10.0"
|
|
167
141
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
168
|
-
checksum = "
|
|
142
|
+
checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6"
|
|
169
143
|
|
|
170
144
|
[[package]]
|
|
171
145
|
name = "proc-macro2"
|
|
172
|
-
version = "1.0.
|
|
146
|
+
version = "1.0.92"
|
|
173
147
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
174
|
-
checksum = "
|
|
148
|
+
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
|
|
175
149
|
dependencies = [
|
|
176
150
|
"unicode-ident",
|
|
177
151
|
]
|
|
178
152
|
|
|
179
153
|
[[package]]
|
|
180
154
|
name = "pyo3"
|
|
181
|
-
version = "0.23.
|
|
155
|
+
version = "0.23.3"
|
|
182
156
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
183
|
-
checksum = "
|
|
157
|
+
checksum = "e484fd2c8b4cb67ab05a318f1fd6fa8f199fcc30819f08f07d200809dba26c15"
|
|
184
158
|
dependencies = [
|
|
185
159
|
"anyhow",
|
|
186
160
|
"cfg-if",
|
|
@@ -197,9 +171,9 @@ dependencies = [
|
|
|
197
171
|
|
|
198
172
|
[[package]]
|
|
199
173
|
name = "pyo3-build-config"
|
|
200
|
-
version = "0.23.
|
|
174
|
+
version = "0.23.3"
|
|
201
175
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
202
|
-
checksum = "
|
|
176
|
+
checksum = "dc0e0469a84f208e20044b98965e1561028180219e35352a2afaf2b942beff3b"
|
|
203
177
|
dependencies = [
|
|
204
178
|
"once_cell",
|
|
205
179
|
"python3-dll-a",
|
|
@@ -208,9 +182,9 @@ dependencies = [
|
|
|
208
182
|
|
|
209
183
|
[[package]]
|
|
210
184
|
name = "pyo3-ffi"
|
|
211
|
-
version = "0.23.
|
|
185
|
+
version = "0.23.3"
|
|
212
186
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
213
|
-
checksum = "
|
|
187
|
+
checksum = "eb1547a7f9966f6f1a0f0227564a9945fe36b90da5a93b3933fc3dc03fae372d"
|
|
214
188
|
dependencies = [
|
|
215
189
|
"libc",
|
|
216
190
|
"pyo3-build-config",
|
|
@@ -218,9 +192,9 @@ dependencies = [
|
|
|
218
192
|
|
|
219
193
|
[[package]]
|
|
220
194
|
name = "pyo3-macros"
|
|
221
|
-
version = "0.23.
|
|
195
|
+
version = "0.23.3"
|
|
222
196
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
223
|
-
checksum = "
|
|
197
|
+
checksum = "fdb6da8ec6fa5cedd1626c886fc8749bdcbb09424a86461eb8cdf096b7c33257"
|
|
224
198
|
dependencies = [
|
|
225
199
|
"proc-macro2",
|
|
226
200
|
"pyo3-macros-backend",
|
|
@@ -230,9 +204,9 @@ dependencies = [
|
|
|
230
204
|
|
|
231
205
|
[[package]]
|
|
232
206
|
name = "pyo3-macros-backend"
|
|
233
|
-
version = "0.23.
|
|
207
|
+
version = "0.23.3"
|
|
234
208
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
235
|
-
checksum = "
|
|
209
|
+
checksum = "38a385202ff5a92791168b1136afae5059d3ac118457bb7bc304c197c2d33e7d"
|
|
236
210
|
dependencies = [
|
|
237
211
|
"heck",
|
|
238
212
|
"proc-macro2",
|
|
@@ -243,9 +217,9 @@ dependencies = [
|
|
|
243
217
|
|
|
244
218
|
[[package]]
|
|
245
219
|
name = "python3-dll-a"
|
|
246
|
-
version = "0.2.
|
|
220
|
+
version = "0.2.12"
|
|
247
221
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
248
|
-
checksum = "
|
|
222
|
+
checksum = "9b66f9171950e674e64bad3456e11bb3cca108e5c34844383cfe277f45c8a7a8"
|
|
249
223
|
dependencies = [
|
|
250
224
|
"cc",
|
|
251
225
|
]
|
|
@@ -261,24 +235,22 @@ dependencies = [
|
|
|
261
235
|
|
|
262
236
|
[[package]]
|
|
263
237
|
name = "redox_syscall"
|
|
264
|
-
version = "0.5.
|
|
238
|
+
version = "0.5.8"
|
|
265
239
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
266
|
-
checksum = "
|
|
240
|
+
checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
|
|
267
241
|
dependencies = [
|
|
268
242
|
"bitflags",
|
|
269
243
|
]
|
|
270
244
|
|
|
271
245
|
[[package]]
|
|
272
246
|
name = "rloop"
|
|
273
|
-
version = "0.1.0-
|
|
247
|
+
version = "0.1.0-alpha3"
|
|
274
248
|
dependencies = [
|
|
275
249
|
"anyhow",
|
|
276
250
|
"dashmap",
|
|
277
|
-
"mimalloc",
|
|
278
251
|
"mio",
|
|
279
252
|
"pyo3",
|
|
280
253
|
"socket2",
|
|
281
|
-
"tikv-jemallocator",
|
|
282
254
|
]
|
|
283
255
|
|
|
284
256
|
[[package]]
|
|
@@ -301,9 +273,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
|
|
301
273
|
|
|
302
274
|
[[package]]
|
|
303
275
|
name = "socket2"
|
|
304
|
-
version = "0.5.
|
|
276
|
+
version = "0.5.8"
|
|
305
277
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
306
|
-
checksum = "
|
|
278
|
+
checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8"
|
|
307
279
|
dependencies = [
|
|
308
280
|
"libc",
|
|
309
281
|
"windows-sys",
|
|
@@ -311,9 +283,9 @@ dependencies = [
|
|
|
311
283
|
|
|
312
284
|
[[package]]
|
|
313
285
|
name = "syn"
|
|
314
|
-
version = "2.0.
|
|
286
|
+
version = "2.0.90"
|
|
315
287
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
316
|
-
checksum = "
|
|
288
|
+
checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31"
|
|
317
289
|
dependencies = [
|
|
318
290
|
"proc-macro2",
|
|
319
291
|
"quote",
|
|
@@ -326,31 +298,11 @@ version = "0.12.16"
|
|
|
326
298
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
327
299
|
checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
|
328
300
|
|
|
329
|
-
[[package]]
|
|
330
|
-
name = "tikv-jemalloc-sys"
|
|
331
|
-
version = "0.6.0+5.3.0-1-ge13ca993e8ccb9ba9847cc330696e02839f328f7"
|
|
332
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
333
|
-
checksum = "cd3c60906412afa9c2b5b5a48ca6a5abe5736aec9eb48ad05037a677e52e4e2d"
|
|
334
|
-
dependencies = [
|
|
335
|
-
"cc",
|
|
336
|
-
"libc",
|
|
337
|
-
]
|
|
338
|
-
|
|
339
|
-
[[package]]
|
|
340
|
-
name = "tikv-jemallocator"
|
|
341
|
-
version = "0.6.0"
|
|
342
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
343
|
-
checksum = "4cec5ff18518d81584f477e9bfdf957f5bb0979b0bac3af4ca30b5b3ae2d2865"
|
|
344
|
-
dependencies = [
|
|
345
|
-
"libc",
|
|
346
|
-
"tikv-jemalloc-sys",
|
|
347
|
-
]
|
|
348
|
-
|
|
349
301
|
[[package]]
|
|
350
302
|
name = "unicode-ident"
|
|
351
|
-
version = "1.0.
|
|
303
|
+
version = "1.0.14"
|
|
352
304
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
353
|
-
checksum = "
|
|
305
|
+
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
|
|
354
306
|
|
|
355
307
|
[[package]]
|
|
356
308
|
name = "unindent"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "rloop"
|
|
3
|
-
version = "0.1.0-
|
|
3
|
+
version = "0.1.0-alpha3"
|
|
4
4
|
description = "An asyncio event loop implemented in Rust"
|
|
5
5
|
authors = ["Giovanni Barillari <g@baro.dev>"]
|
|
6
6
|
license = "BSD-3-Clause"
|
|
@@ -36,12 +36,6 @@ mio = { version = "=1.0", features = ["net", "os-ext", "os-poll"] }
|
|
|
36
36
|
pyo3 = { version = "=0.23", features = ["anyhow", "extension-module", "generate-import-lib"] }
|
|
37
37
|
socket2 = "=0.5"
|
|
38
38
|
|
|
39
|
-
[target.'cfg(any(target_os = "freebsd", target_os = "windows"))'.dependencies]
|
|
40
|
-
mimalloc = { version = "0.1.43", default-features = false, features = ["local_dynamic_tls"] }
|
|
41
|
-
|
|
42
|
-
[target.'cfg(not(any(target_os = "freebsd", target_os = "windows")))'.dependencies]
|
|
43
|
-
tikv-jemallocator = { version = "0.6.0", default-features = false, features = ["disable_initial_exec_tls"] }
|
|
44
|
-
|
|
45
39
|
[profile.release]
|
|
46
40
|
codegen-units = 1
|
|
47
41
|
debug = false
|
|
@@ -35,8 +35,6 @@ class EventLoop:
|
|
|
35
35
|
_watcher_child: Any
|
|
36
36
|
|
|
37
37
|
def _run(self): ...
|
|
38
|
-
def _wake(self): ...
|
|
39
|
-
def _call_soon(self, callback, args, context) -> CBHandle: ...
|
|
40
38
|
def _call_later(self, delay, callback, args, context) -> TimerHandle: ...
|
|
41
39
|
def _reader_add(self, fd, callback, args, context) -> CBHandle: ...
|
|
42
40
|
def _reader_rem(self, fd) -> bool: ...
|
|
@@ -45,7 +43,7 @@ class EventLoop:
|
|
|
45
43
|
def _sig_add(self, sig, callback, context): ...
|
|
46
44
|
def _sig_rem(self, sig) -> bool: ...
|
|
47
45
|
def _sig_clear(self): ...
|
|
48
|
-
def _sig_handle(self, sig) -> bool: ...
|
|
49
|
-
def _sig_ceval(self, noop: Any): ...
|
|
50
46
|
def _ssock_set(self, fd): ...
|
|
51
47
|
def _ssock_del(self, fd): ...
|
|
48
|
+
def call_soon(self, callback, *args, context=None) -> CBHandle: ...
|
|
49
|
+
def call_soon_threadsafe(self, callback, *args, context=None) -> CBHandle: ...
|
|
@@ -210,19 +210,16 @@ class RLoop(__BaseLoop, __asyncio.AbstractEventLoop):
|
|
|
210
210
|
# def _timer_handle_cancelled(self, handle):
|
|
211
211
|
# raise NotImplementedError
|
|
212
212
|
|
|
213
|
-
def call_soon(self, callback, *args, context=None) -> CBHandle:
|
|
214
|
-
return self._call_soon(callback, args, context or _copy_context())
|
|
215
|
-
|
|
216
213
|
def call_later(self, delay, callback, *args, context=None) -> Union[CBHandle, TimerHandle]:
|
|
217
214
|
if delay <= 0:
|
|
218
|
-
return self.
|
|
215
|
+
return self.call_soon(callback, *args, context=context or _copy_context())
|
|
219
216
|
delay = round(delay * 1_000_000)
|
|
220
217
|
return self._call_later(delay, callback, args, context or _copy_context())
|
|
221
218
|
|
|
222
219
|
def call_at(self, when, callback, *args, context=None) -> Union[CBHandle, TimerHandle]:
|
|
223
220
|
delay = round((when - self.time()) * 1_000_000)
|
|
224
221
|
if delay <= 0:
|
|
225
|
-
return self.
|
|
222
|
+
return self.call_soon(callback, *args, context=context or _copy_context())
|
|
226
223
|
return self._call_later(delay, callback, args, context or _copy_context())
|
|
227
224
|
|
|
228
225
|
def time(self) -> float:
|
|
@@ -269,11 +266,6 @@ class RLoop(__BaseLoop, __asyncio.AbstractEventLoop):
|
|
|
269
266
|
return task
|
|
270
267
|
|
|
271
268
|
#: threads methods
|
|
272
|
-
def call_soon_threadsafe(self, callback, *args, context=None) -> CBHandle:
|
|
273
|
-
rv = self._call_soon(callback, args, context or self._base_ctx)
|
|
274
|
-
self._wake()
|
|
275
|
-
return rv
|
|
276
|
-
|
|
277
269
|
def run_in_executor(self, executor, fn, *args):
|
|
278
270
|
if _iscoroutine(fn) or _iscoroutinefunction(fn):
|
|
279
271
|
raise TypeError('Coroutines cannot be used with executors')
|
|
@@ -675,41 +667,21 @@ class RLoop(__BaseLoop, __asyncio.AbstractEventLoop):
|
|
|
675
667
|
try:
|
|
676
668
|
self._ssock_r.setblocking(False)
|
|
677
669
|
self._ssock_w.setblocking(False)
|
|
678
|
-
self._ssock_set(self._ssock_w.fileno())
|
|
670
|
+
self._ssock_set(self._ssock_r.fileno(), self._ssock_w.fileno())
|
|
679
671
|
except Exception:
|
|
680
|
-
self._ssock_del()
|
|
681
|
-
self._ssock_r.close()
|
|
672
|
+
self._ssock_del(self._ssock_r.fileno())
|
|
682
673
|
self._ssock_w = None
|
|
683
674
|
self._ssock_r = None
|
|
684
675
|
raise
|
|
685
676
|
|
|
686
|
-
self._reader_add(self._ssock_r.fileno(), self._ssock_reader, (), _copy_context())
|
|
687
|
-
|
|
688
677
|
def _ssock_stop(self):
|
|
689
678
|
if not self._ssock_w:
|
|
690
679
|
raise RuntimeError('self-socket has not been setup')
|
|
691
680
|
|
|
692
|
-
self.
|
|
693
|
-
self._ssock_del()
|
|
694
|
-
self._ssock_r.close()
|
|
681
|
+
self._ssock_del(self._ssock_r.fileno())
|
|
695
682
|
self._ssock_w = None
|
|
696
683
|
self._ssock_r = None
|
|
697
684
|
|
|
698
|
-
def _ssock_reader(self):
|
|
699
|
-
sigdata = b''
|
|
700
|
-
while True:
|
|
701
|
-
try:
|
|
702
|
-
data = self._ssock_r.recv(65536)
|
|
703
|
-
if not data:
|
|
704
|
-
break
|
|
705
|
-
sigdata += data
|
|
706
|
-
except InterruptedError:
|
|
707
|
-
continue
|
|
708
|
-
except BlockingIOError:
|
|
709
|
-
break
|
|
710
|
-
if sigdata and self._sig_listening:
|
|
711
|
-
self._signals_invoke(sigdata)
|
|
712
|
-
|
|
713
685
|
def add_signal_handler(self, sig, callback, *args):
|
|
714
686
|
if not self.__is_main_thread():
|
|
715
687
|
raise ValueError('Signals can only be handled from the main thread')
|
|
@@ -718,10 +690,11 @@ class RLoop(__BaseLoop, __asyncio.AbstractEventLoop):
|
|
|
718
690
|
raise TypeError('Coroutines cannot be used as signals handlers')
|
|
719
691
|
|
|
720
692
|
self._check_closed()
|
|
721
|
-
self.
|
|
693
|
+
self._check_signal(sig)
|
|
694
|
+
self._sig_add(sig, callback, args, _copy_context())
|
|
722
695
|
try:
|
|
723
696
|
# register a dummy signal handler so Python will write the signal no in the wakeup fd
|
|
724
|
-
signal.signal(sig,
|
|
697
|
+
signal.signal(sig, _noop)
|
|
725
698
|
# set SA_RESTART to limit EINTR occurrences
|
|
726
699
|
signal.siginterrupt(sig, False)
|
|
727
700
|
except OSError as exc:
|
|
@@ -734,13 +707,32 @@ class RLoop(__BaseLoop, __asyncio.AbstractEventLoop):
|
|
|
734
707
|
if not self._is_main_thread():
|
|
735
708
|
raise ValueError('Signals can only be handled from the main thread')
|
|
736
709
|
|
|
737
|
-
|
|
710
|
+
if not self._sig_rem(sig):
|
|
711
|
+
return False
|
|
712
|
+
|
|
713
|
+
if sig == signal.SIGINT:
|
|
714
|
+
handler = signal.default_int_handler
|
|
715
|
+
else:
|
|
716
|
+
handler = signal.SIG_DFL
|
|
717
|
+
|
|
718
|
+
try:
|
|
719
|
+
signal.signal(sig, handler)
|
|
720
|
+
except OSError as exc:
|
|
721
|
+
if exc.errno == errno.EINVAL:
|
|
722
|
+
raise RuntimeError(f'signum {sig} cannot be caught')
|
|
723
|
+
raise
|
|
724
|
+
|
|
725
|
+
return True
|
|
738
726
|
|
|
739
727
|
def __is_main_thread(self):
|
|
740
728
|
return threading.main_thread().ident == threading.current_thread().ident
|
|
741
729
|
|
|
742
|
-
def
|
|
743
|
-
|
|
730
|
+
def _check_signal(self, sig):
|
|
731
|
+
if not isinstance(sig, int):
|
|
732
|
+
raise TypeError(f'sig must be an int, not {sig!r}')
|
|
733
|
+
|
|
734
|
+
if sig not in signal.valid_signals():
|
|
735
|
+
raise ValueError(f'invalid signal number {sig}')
|
|
744
736
|
|
|
745
737
|
def __set_sig_wfd(self, fd):
|
|
746
738
|
if fd >= 0:
|
|
@@ -786,25 +778,6 @@ class RLoop(__BaseLoop, __asyncio.AbstractEventLoop):
|
|
|
786
778
|
|
|
787
779
|
self._sig_clear()
|
|
788
780
|
|
|
789
|
-
def _signals_invoke(self, data):
|
|
790
|
-
self._sig_ceval(_noop)
|
|
791
|
-
self._sig_loop_handled = True
|
|
792
|
-
|
|
793
|
-
sigs = self._signals.copy()
|
|
794
|
-
self._signals.clear()
|
|
795
|
-
for signum in data:
|
|
796
|
-
if not signum:
|
|
797
|
-
continue
|
|
798
|
-
sigs.discard(signum)
|
|
799
|
-
self._signal_handle(signum)
|
|
800
|
-
|
|
801
|
-
for signum in sigs:
|
|
802
|
-
self._signal_handle(signum)
|
|
803
|
-
|
|
804
|
-
def _signal_handle(self, signum):
|
|
805
|
-
if not self._sig_handle(signum):
|
|
806
|
-
self._sig_ceval(_noop)
|
|
807
|
-
|
|
808
781
|
#: task factory
|
|
809
782
|
def set_task_factory(self, factory):
|
|
810
783
|
self._task_factory = factory
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
use std::{
|
|
2
2
|
cmp::Ordering,
|
|
3
3
|
collections::{BinaryHeap, VecDeque},
|
|
4
|
-
io::Write,
|
|
4
|
+
io::{Read, Write},
|
|
5
5
|
mem,
|
|
6
6
|
os::fd::FromRawFd,
|
|
7
7
|
sync::{atomic, Arc, Mutex, RwLock},
|
|
@@ -11,13 +11,10 @@ use std::{
|
|
|
11
11
|
use anyhow::Result;
|
|
12
12
|
use dashmap::DashMap;
|
|
13
13
|
use mio::{Events, Interest, Poll, Token};
|
|
14
|
-
use pyo3::{
|
|
15
|
-
prelude::*,
|
|
16
|
-
types::{PyDict, PySet, PyTuple},
|
|
17
|
-
};
|
|
14
|
+
use pyo3::{prelude::*, types::PyDict};
|
|
18
15
|
|
|
19
16
|
use crate::handles::{CBHandle, TimerHandle};
|
|
20
|
-
use crate::io::Source;
|
|
17
|
+
use crate::io::{InternalIO, Source};
|
|
21
18
|
use crate::py::{copy_context, weakset};
|
|
22
19
|
|
|
23
20
|
struct Timer {
|
|
@@ -51,7 +48,19 @@ impl Ord for Timer {
|
|
|
51
48
|
}
|
|
52
49
|
}
|
|
53
50
|
|
|
51
|
+
enum IOHandle {
|
|
52
|
+
Internal(IOHandleData),
|
|
53
|
+
Py(PyIOHandleData),
|
|
54
|
+
}
|
|
55
|
+
|
|
54
56
|
struct IOHandleData {
|
|
57
|
+
source: Source,
|
|
58
|
+
#[allow(dead_code)]
|
|
59
|
+
interest: Interest,
|
|
60
|
+
handle: InternalIO,
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
struct PyIOHandleData {
|
|
55
64
|
source: Source,
|
|
56
65
|
interest: Interest,
|
|
57
66
|
cbr: Option<Py<CBHandle>>,
|
|
@@ -60,20 +69,21 @@ struct IOHandleData {
|
|
|
60
69
|
|
|
61
70
|
#[pyclass(frozen, subclass)]
|
|
62
71
|
struct EventLoop {
|
|
72
|
+
idle: atomic::AtomicBool,
|
|
63
73
|
io: Arc<Mutex<Poll>>,
|
|
64
|
-
handles_io: Arc<DashMap<Token,
|
|
74
|
+
handles_io: Arc<DashMap<Token, IOHandle>>,
|
|
65
75
|
handles_ready: Arc<Mutex<VecDeque<Py<CBHandle>>>>,
|
|
66
76
|
handles_sched: Arc<Mutex<BinaryHeap<Timer>>>,
|
|
67
77
|
epoch: Instant,
|
|
68
78
|
counter_ready: atomic::AtomicUsize,
|
|
69
79
|
counter_io: atomic::AtomicU16,
|
|
70
|
-
ssock: Arc<RwLock<Option<socket2::Socket>>>,
|
|
80
|
+
ssock: Arc<RwLock<Option<(socket2::Socket, socket2::Socket)>>>,
|
|
71
81
|
tick_last_poll: atomic::AtomicU64,
|
|
72
82
|
closed: atomic::AtomicBool,
|
|
73
83
|
exc_handler: Arc<RwLock<PyObject>>,
|
|
74
84
|
exception_handler: Arc<RwLock<PyObject>>,
|
|
75
85
|
executor: Arc<RwLock<PyObject>>,
|
|
76
|
-
sig_handlers: Arc<DashMap<
|
|
86
|
+
sig_handlers: Arc<DashMap<u8, Py<CBHandle>>>,
|
|
77
87
|
sig_listening: atomic::AtomicBool,
|
|
78
88
|
sig_loop_handled: atomic::AtomicBool,
|
|
79
89
|
sig_wfd: Arc<RwLock<PyObject>>,
|
|
@@ -89,8 +99,6 @@ struct EventLoop {
|
|
|
89
99
|
_asyncgens: PyObject,
|
|
90
100
|
#[pyo3(get)]
|
|
91
101
|
_base_ctx: PyObject,
|
|
92
|
-
#[pyo3(get)]
|
|
93
|
-
_signals: Py<PySet>,
|
|
94
102
|
}
|
|
95
103
|
|
|
96
104
|
impl EventLoop {
|
|
@@ -104,16 +112,9 @@ impl EventLoop {
|
|
|
104
112
|
if self.counter_ready.load(atomic::Ordering::Relaxed) > 0 {
|
|
105
113
|
sched_time = Some(0);
|
|
106
114
|
// we want to skip polling when unnecessary:
|
|
107
|
-
//
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
if self.counter_io.load(atomic::Ordering::Relaxed) > 1 {
|
|
111
|
-
// we max out at 250μs poll intervals
|
|
112
|
-
let tick = Instant::now().duration_since(self.epoch).as_micros() as u64;
|
|
113
|
-
if (tick - self.tick_last_poll.load(atomic::Ordering::Relaxed)) < 250 {
|
|
114
|
-
skip_poll = true;
|
|
115
|
-
}
|
|
116
|
-
} else {
|
|
115
|
+
// if work is ready we check the time since last poll and skip for max 250μs
|
|
116
|
+
let tick = Instant::now().duration_since(self.epoch).as_micros() as u64;
|
|
117
|
+
if (tick - self.tick_last_poll.load(atomic::Ordering::Relaxed)) < 250 {
|
|
117
118
|
skip_poll = true;
|
|
118
119
|
}
|
|
119
120
|
} else {
|
|
@@ -133,6 +134,9 @@ impl EventLoop {
|
|
|
133
134
|
true => Ok(()),
|
|
134
135
|
false => py.allow_threads(|| {
|
|
135
136
|
let mut io = self.io.lock().unwrap();
|
|
137
|
+
if sched_time.is_none() {
|
|
138
|
+
self.idle.store(true, atomic::Ordering::Relaxed);
|
|
139
|
+
}
|
|
136
140
|
let res = io.poll(&mut io_events, sched_time.map(Duration::from_millis));
|
|
137
141
|
if let Err(ref err) = res {
|
|
138
142
|
if err.kind() == std::io::ErrorKind::Interrupted {
|
|
@@ -140,6 +144,7 @@ impl EventLoop {
|
|
|
140
144
|
let _ = io.poll(&mut io_events, Some(Duration::from_millis(0)));
|
|
141
145
|
}
|
|
142
146
|
}
|
|
147
|
+
self.idle.store(false, atomic::Ordering::Relaxed);
|
|
143
148
|
self.tick_last_poll.store(
|
|
144
149
|
Instant::now().duration_since(self.epoch).as_micros() as u64,
|
|
145
150
|
atomic::Ordering::Relaxed,
|
|
@@ -148,20 +153,28 @@ impl EventLoop {
|
|
|
148
153
|
}),
|
|
149
154
|
};
|
|
150
155
|
let mut guard_cb = self.handles_ready.lock().unwrap();
|
|
151
|
-
|
|
156
|
+
let mut cb_handles = mem::replace(&mut *guard_cb, VecDeque::with_capacity(128));
|
|
157
|
+
self.counter_ready
|
|
158
|
+
.fetch_sub(cb_handles.len(), atomic::Ordering::Relaxed);
|
|
159
|
+
drop(guard_cb);
|
|
152
160
|
|
|
153
161
|
for event in &io_events {
|
|
154
162
|
// NOTE: cancellation is not necessary as we have custom futures
|
|
155
|
-
if let Some(
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
163
|
+
if let Some(io_handle) = self.handles_io.get(&event.token()) {
|
|
164
|
+
match io_handle.value() {
|
|
165
|
+
IOHandle::Py(handle) => {
|
|
166
|
+
if let Some(cbr) = &handle.cbr {
|
|
167
|
+
if event.is_readable() {
|
|
168
|
+
cb_handles.push_back(cbr.clone_ref(py));
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if let Some(cbw) = &handle.cbw {
|
|
172
|
+
if event.is_writable() {
|
|
173
|
+
cb_handles.push_back(cbw.clone_ref(py));
|
|
174
|
+
}
|
|
175
|
+
}
|
|
164
176
|
}
|
|
177
|
+
IOHandle::Internal(handle) => self.handle_internal_io(handle, py, &mut cb_handles),
|
|
165
178
|
}
|
|
166
179
|
}
|
|
167
180
|
}
|
|
@@ -175,15 +188,13 @@ impl EventLoop {
|
|
|
175
188
|
if timer.when > tick {
|
|
176
189
|
break;
|
|
177
190
|
}
|
|
178
|
-
|
|
191
|
+
cb_handles.push_back(guard_sched.pop().unwrap().handle);
|
|
179
192
|
}
|
|
180
193
|
}
|
|
181
194
|
}
|
|
182
195
|
drop(guard_sched);
|
|
183
196
|
|
|
184
197
|
// callbacks
|
|
185
|
-
let mut cb_handles = mem::replace(&mut *guard_cb, VecDeque::with_capacity(128));
|
|
186
|
-
drop(guard_cb);
|
|
187
198
|
while let Some(cb_handle) = cb_handles.pop_front() {
|
|
188
199
|
// let handle = match cb_handle {
|
|
189
200
|
// Handle::Callback(ref v) => v.get(),
|
|
@@ -207,9 +218,71 @@ impl EventLoop {
|
|
|
207
218
|
poll_result
|
|
208
219
|
}
|
|
209
220
|
|
|
221
|
+
#[inline]
|
|
222
|
+
fn handle_internal_io(&self, handle_data: &IOHandleData, py: Python, handles_ready: &mut VecDeque<Py<CBHandle>>) {
|
|
223
|
+
match handle_data.handle {
|
|
224
|
+
InternalIO::Signals => {
|
|
225
|
+
let sigs = py.allow_threads(|| self.read_from_self());
|
|
226
|
+
for sig in sigs {
|
|
227
|
+
self.sig_handle(py, sig, handles_ready);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
#[inline]
|
|
234
|
+
fn sig_handle(&self, py: Python, sig: u8, handles_ready: &mut VecDeque<Py<CBHandle>>) {
|
|
235
|
+
if let Some(pyhandle) = self.sig_handlers.get(&sig) {
|
|
236
|
+
self.sig_loop_handled.store(true, atomic::Ordering::Relaxed);
|
|
237
|
+
|
|
238
|
+
if pyhandle.get().cancelled.load(atomic::Ordering::Relaxed) {
|
|
239
|
+
self._sig_rem(sig);
|
|
240
|
+
} else {
|
|
241
|
+
handles_ready.push_back(pyhandle.clone_ref(py));
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
#[inline(always)]
|
|
247
|
+
fn wake(&self) {
|
|
248
|
+
let mut guard = self.ssock.write().unwrap();
|
|
249
|
+
if let Some((_, sockw)) = guard.as_mut() {
|
|
250
|
+
let _ = sockw.write(b"\0");
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
fn read_from_self(&self) -> Vec<u8> {
|
|
255
|
+
let mut guard = self.ssock.write().unwrap();
|
|
256
|
+
if let Some((sockr, _)) = guard.as_mut() {
|
|
257
|
+
let mut buf = [0; 4096];
|
|
258
|
+
let mut len = 0;
|
|
259
|
+
loop {
|
|
260
|
+
match sockr.read(&mut buf[len..]) {
|
|
261
|
+
Ok(0) => break,
|
|
262
|
+
Ok(readn) => {
|
|
263
|
+
len += readn;
|
|
264
|
+
}
|
|
265
|
+
Err(err) if err.kind() == std::io::ErrorKind::Interrupted => continue,
|
|
266
|
+
Err(_) => break,
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if self.sig_listening.load(atomic::Ordering::Relaxed) {
|
|
270
|
+
let mut sigs = Vec::with_capacity(len);
|
|
271
|
+
for sig in &buf[..len] {
|
|
272
|
+
if *sig == 0 {
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
sigs.push(*sig);
|
|
276
|
+
}
|
|
277
|
+
return sigs;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
Vec::new()
|
|
281
|
+
}
|
|
282
|
+
|
|
210
283
|
#[inline]
|
|
211
284
|
fn reader_rem(&self, token: Token) -> Result<bool> {
|
|
212
|
-
if let Some((_, mut item)) = self.handles_io.remove(&token) {
|
|
285
|
+
if let Some((_, IOHandle::Py(mut item))) = self.handles_io.remove(&token) {
|
|
213
286
|
let guard_poll = self.io.lock().unwrap();
|
|
214
287
|
match item.interest {
|
|
215
288
|
Interest::READABLE => {
|
|
@@ -221,12 +294,12 @@ impl EventLoop {
|
|
|
221
294
|
guard_poll.registry().reregister(&mut item.source, token, interest)?;
|
|
222
295
|
self.handles_io.insert(
|
|
223
296
|
token,
|
|
224
|
-
|
|
297
|
+
IOHandle::Py(PyIOHandleData {
|
|
225
298
|
source: item.source,
|
|
226
299
|
interest,
|
|
227
300
|
cbr: None,
|
|
228
301
|
cbw: item.cbw,
|
|
229
|
-
},
|
|
302
|
+
}),
|
|
230
303
|
);
|
|
231
304
|
}
|
|
232
305
|
}
|
|
@@ -237,7 +310,7 @@ impl EventLoop {
|
|
|
237
310
|
|
|
238
311
|
#[inline]
|
|
239
312
|
fn writer_rem(&self, token: Token) -> Result<bool> {
|
|
240
|
-
if let Some((_, mut item)) = self.handles_io.remove(&token) {
|
|
313
|
+
if let Some((_, IOHandle::Py(mut item))) = self.handles_io.remove(&token) {
|
|
241
314
|
let guard_poll = self.io.lock().unwrap();
|
|
242
315
|
match item.interest {
|
|
243
316
|
Interest::WRITABLE => {
|
|
@@ -249,12 +322,12 @@ impl EventLoop {
|
|
|
249
322
|
guard_poll.registry().reregister(&mut item.source, token, interest)?;
|
|
250
323
|
self.handles_io.insert(
|
|
251
324
|
token,
|
|
252
|
-
|
|
325
|
+
IOHandle::Py(PyIOHandleData {
|
|
253
326
|
source: item.source,
|
|
254
327
|
interest,
|
|
255
328
|
cbr: item.cbr,
|
|
256
329
|
cbw: None,
|
|
257
|
-
},
|
|
330
|
+
}),
|
|
258
331
|
);
|
|
259
332
|
}
|
|
260
333
|
}
|
|
@@ -263,14 +336,6 @@ impl EventLoop {
|
|
|
263
336
|
Ok(false)
|
|
264
337
|
}
|
|
265
338
|
|
|
266
|
-
#[inline]
|
|
267
|
-
fn wake(&self) {
|
|
268
|
-
let mut guard = self.ssock.write().unwrap();
|
|
269
|
-
if let Some(sock) = guard.as_mut() {
|
|
270
|
-
let _ = sock.write(b"\0");
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
339
|
fn log_exception(&self, py: Python, ctx: Bound<PyDict>) -> PyResult<PyObject> {
|
|
275
340
|
let handler = self.exc_handler.read().unwrap();
|
|
276
341
|
handler.call1(py, (ctx, self.exception_handler.read().unwrap().clone_ref(py)))
|
|
@@ -282,6 +347,7 @@ impl EventLoop {
|
|
|
282
347
|
#[new]
|
|
283
348
|
fn new(py: Python) -> PyResult<Self> {
|
|
284
349
|
Ok(Self {
|
|
350
|
+
idle: atomic::AtomicBool::new(false),
|
|
285
351
|
io: Arc::new(Mutex::new(Poll::new()?)),
|
|
286
352
|
handles_io: Arc::new(DashMap::with_capacity(128)),
|
|
287
353
|
handles_ready: Arc::new(Mutex::new(VecDeque::with_capacity(128))),
|
|
@@ -309,7 +375,6 @@ impl EventLoop {
|
|
|
309
375
|
watcher_child: Arc::new(RwLock::new(py.None())),
|
|
310
376
|
_asyncgens: weakset(py)?.unbind(),
|
|
311
377
|
_base_ctx: copy_context(py)?.unbind(),
|
|
312
|
-
_signals: PySet::empty(py)?.into_pyobject(py)?.unbind(),
|
|
313
378
|
})
|
|
314
379
|
}
|
|
315
380
|
|
|
@@ -411,16 +476,6 @@ impl EventLoop {
|
|
|
411
476
|
self.sig_listening.store(val, atomic::Ordering::Relaxed);
|
|
412
477
|
}
|
|
413
478
|
|
|
414
|
-
#[getter(_sig_loop_handled)]
|
|
415
|
-
fn _get_sig_loop_handled(&self) -> bool {
|
|
416
|
-
self.sig_loop_handled.load(atomic::Ordering::Relaxed)
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
#[setter(_sig_loop_handled)]
|
|
420
|
-
fn _set_sig_loop_handled(&self, val: bool) {
|
|
421
|
-
self.sig_loop_handled.store(val, atomic::Ordering::Relaxed);
|
|
422
|
-
}
|
|
423
|
-
|
|
424
479
|
#[getter(_sig_wfd)]
|
|
425
480
|
fn _get_sig_wfd(&self, py: Python) -> PyObject {
|
|
426
481
|
self.sig_wfd.read().unwrap().clone_ref(py)
|
|
@@ -476,21 +531,84 @@ impl EventLoop {
|
|
|
476
531
|
*guard = factory;
|
|
477
532
|
}
|
|
478
533
|
|
|
479
|
-
fn _ssock_set(&self,
|
|
534
|
+
fn _ssock_set(&self, fd_r: usize, fd_w: usize) -> PyResult<()> {
|
|
480
535
|
let mut guard = self.ssock.write().unwrap();
|
|
481
|
-
*guard = Some(unsafe {
|
|
536
|
+
*guard = Some(unsafe {
|
|
537
|
+
(
|
|
538
|
+
#[allow(clippy::cast_possible_wrap)]
|
|
539
|
+
socket2::Socket::from_raw_fd(fd_r as i32),
|
|
540
|
+
#[allow(clippy::cast_possible_wrap)]
|
|
541
|
+
socket2::Socket::from_raw_fd(fd_w as i32),
|
|
542
|
+
)
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
let token = Token(fd_r);
|
|
546
|
+
let mut source = Source::FD(fd_r.try_into()?);
|
|
547
|
+
let interest = Interest::READABLE;
|
|
548
|
+
let guard_poll = self.io.lock().unwrap();
|
|
549
|
+
guard_poll.registry().register(&mut source, token, interest)?;
|
|
550
|
+
drop(guard_poll);
|
|
551
|
+
self.handles_io.insert(
|
|
552
|
+
token,
|
|
553
|
+
IOHandle::Internal(IOHandleData {
|
|
554
|
+
source,
|
|
555
|
+
interest,
|
|
556
|
+
handle: InternalIO::Signals,
|
|
557
|
+
}),
|
|
558
|
+
);
|
|
559
|
+
|
|
560
|
+
Ok(())
|
|
482
561
|
}
|
|
483
562
|
|
|
484
|
-
fn _ssock_del(&self) {
|
|
563
|
+
fn _ssock_del(&self, fd_r: usize) -> PyResult<()> {
|
|
564
|
+
let token = Token(fd_r);
|
|
565
|
+
if let Some((_, IOHandle::Internal(mut item))) = self.handles_io.remove(&token) {
|
|
566
|
+
let guard_poll = self.io.lock().unwrap();
|
|
567
|
+
guard_poll.registry().deregister(&mut item.source)?;
|
|
568
|
+
}
|
|
485
569
|
self.ssock.write().unwrap().take();
|
|
570
|
+
Ok(())
|
|
486
571
|
}
|
|
487
572
|
|
|
488
|
-
|
|
489
|
-
|
|
573
|
+
#[pyo3(signature = (callback, *args, context=None))]
|
|
574
|
+
fn call_soon(
|
|
575
|
+
&self,
|
|
576
|
+
py: Python,
|
|
577
|
+
callback: PyObject,
|
|
578
|
+
args: PyObject,
|
|
579
|
+
context: Option<PyObject>,
|
|
580
|
+
) -> PyResult<Py<CBHandle>> {
|
|
581
|
+
let handle = Py::new(
|
|
582
|
+
py,
|
|
583
|
+
CBHandle::new(callback, args, context.unwrap_or_else(|| self._base_ctx.clone_ref(py))),
|
|
584
|
+
)?;
|
|
585
|
+
let mut guard = self.handles_ready.lock().unwrap();
|
|
586
|
+
guard.push_back(handle.clone_ref(py));
|
|
587
|
+
self.counter_ready.fetch_add(1, atomic::Ordering::Relaxed);
|
|
588
|
+
drop(guard);
|
|
589
|
+
Ok(handle)
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
#[pyo3(signature = (callback, *args, context=None))]
|
|
593
|
+
fn call_soon_threadsafe(
|
|
594
|
+
&self,
|
|
595
|
+
py: Python,
|
|
596
|
+
callback: PyObject,
|
|
597
|
+
args: PyObject,
|
|
598
|
+
context: Option<PyObject>,
|
|
599
|
+
) -> PyResult<Py<CBHandle>> {
|
|
600
|
+
let handle = Py::new(
|
|
601
|
+
py,
|
|
602
|
+
CBHandle::new(callback, args, context.unwrap_or_else(|| self._base_ctx.clone_ref(py))),
|
|
603
|
+
)?;
|
|
490
604
|
let mut guard = self.handles_ready.lock().unwrap();
|
|
491
605
|
guard.push_back(handle.clone_ref(py));
|
|
492
606
|
self.counter_ready.fetch_add(1, atomic::Ordering::Relaxed);
|
|
493
607
|
drop(guard);
|
|
608
|
+
// wake when necessary
|
|
609
|
+
if self.idle.load(atomic::Ordering::Relaxed) {
|
|
610
|
+
py.allow_threads(|| self.wake());
|
|
611
|
+
}
|
|
494
612
|
Ok(handle)
|
|
495
613
|
}
|
|
496
614
|
|
|
@@ -521,33 +639,34 @@ impl EventLoop {
|
|
|
521
639
|
) -> PyResult<Py<CBHandle>> {
|
|
522
640
|
let token = Token(fd);
|
|
523
641
|
let handle = Py::new(py, CBHandle::new(callback, args, context))?;
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
let interest =
|
|
642
|
+
if let Some(mut item) = self.handles_io.get_mut(&token) {
|
|
643
|
+
if let IOHandle::Py(data) = item.value_mut() {
|
|
644
|
+
let interest = data.interest | Interest::READABLE;
|
|
527
645
|
let guard_poll = self.io.lock().unwrap();
|
|
528
|
-
guard_poll.registry().reregister(&mut
|
|
646
|
+
guard_poll.registry().reregister(&mut data.source, token, interest)?;
|
|
529
647
|
drop(guard_poll);
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
_ => {
|
|
534
|
-
let mut source = Source::FD(fd.try_into()?);
|
|
535
|
-
let interest = Interest::READABLE;
|
|
536
|
-
let guard_poll = self.io.lock().unwrap();
|
|
537
|
-
guard_poll.registry().register(&mut source, token, interest)?;
|
|
538
|
-
drop(guard_poll);
|
|
539
|
-
self.handles_io.insert(
|
|
540
|
-
token,
|
|
541
|
-
IOHandleData {
|
|
542
|
-
source,
|
|
543
|
-
interest,
|
|
544
|
-
cbr: Some(handle.clone_ref(py)),
|
|
545
|
-
cbw: None,
|
|
546
|
-
},
|
|
547
|
-
);
|
|
548
|
-
self.counter_io.fetch_add(1, atomic::Ordering::Relaxed);
|
|
648
|
+
data.interest = interest;
|
|
649
|
+
data.cbr = Some(handle.clone_ref(py));
|
|
650
|
+
return Ok(handle);
|
|
549
651
|
}
|
|
550
652
|
}
|
|
653
|
+
|
|
654
|
+
let mut source = Source::FD(fd.try_into()?);
|
|
655
|
+
let interest = Interest::READABLE;
|
|
656
|
+
let guard_poll = self.io.lock().unwrap();
|
|
657
|
+
guard_poll.registry().register(&mut source, token, interest)?;
|
|
658
|
+
drop(guard_poll);
|
|
659
|
+
self.handles_io.insert(
|
|
660
|
+
token,
|
|
661
|
+
IOHandle::Py(PyIOHandleData {
|
|
662
|
+
source,
|
|
663
|
+
interest,
|
|
664
|
+
cbr: Some(handle.clone_ref(py)),
|
|
665
|
+
cbw: None,
|
|
666
|
+
}),
|
|
667
|
+
);
|
|
668
|
+
self.counter_io.fetch_add(1, atomic::Ordering::Relaxed);
|
|
669
|
+
|
|
551
670
|
Ok(handle)
|
|
552
671
|
}
|
|
553
672
|
|
|
@@ -566,33 +685,35 @@ impl EventLoop {
|
|
|
566
685
|
) -> PyResult<Py<CBHandle>> {
|
|
567
686
|
let token = Token(fd);
|
|
568
687
|
let handle = Py::new(py, CBHandle::new(callback, args, context))?;
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
let
|
|
573
|
-
guard_poll.registry().reregister(&mut item.source, token, interest)?;
|
|
574
|
-
drop(guard_poll);
|
|
575
|
-
item.interest = interest;
|
|
576
|
-
item.cbw = Some(handle.clone_ref(py));
|
|
577
|
-
}
|
|
578
|
-
_ => {
|
|
579
|
-
let mut source = Source::FD(fd.try_into()?);
|
|
580
|
-
let interest = Interest::WRITABLE;
|
|
688
|
+
|
|
689
|
+
if let Some(mut item) = self.handles_io.get_mut(&token) {
|
|
690
|
+
if let IOHandle::Py(data) = item.value_mut() {
|
|
691
|
+
let interest = data.interest | Interest::WRITABLE;
|
|
581
692
|
let guard_poll = self.io.lock().unwrap();
|
|
582
|
-
guard_poll.registry().
|
|
693
|
+
guard_poll.registry().reregister(&mut data.source, token, interest)?;
|
|
583
694
|
drop(guard_poll);
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
source,
|
|
588
|
-
interest,
|
|
589
|
-
cbr: None,
|
|
590
|
-
cbw: Some(handle.clone_ref(py)),
|
|
591
|
-
},
|
|
592
|
-
);
|
|
593
|
-
self.counter_io.fetch_add(1, atomic::Ordering::Relaxed);
|
|
695
|
+
data.interest = interest;
|
|
696
|
+
data.cbw = Some(handle.clone_ref(py));
|
|
697
|
+
return Ok(handle);
|
|
594
698
|
}
|
|
595
699
|
}
|
|
700
|
+
|
|
701
|
+
let mut source = Source::FD(fd.try_into()?);
|
|
702
|
+
let interest = Interest::WRITABLE;
|
|
703
|
+
let guard_poll = self.io.lock().unwrap();
|
|
704
|
+
guard_poll.registry().register(&mut source, token, interest)?;
|
|
705
|
+
drop(guard_poll);
|
|
706
|
+
self.handles_io.insert(
|
|
707
|
+
token,
|
|
708
|
+
IOHandle::Py(PyIOHandleData {
|
|
709
|
+
source,
|
|
710
|
+
interest,
|
|
711
|
+
cbr: None,
|
|
712
|
+
cbw: Some(handle.clone_ref(py)),
|
|
713
|
+
}),
|
|
714
|
+
);
|
|
715
|
+
self.counter_io.fetch_add(1, atomic::Ordering::Relaxed);
|
|
716
|
+
|
|
596
717
|
Ok(handle)
|
|
597
718
|
}
|
|
598
719
|
|
|
@@ -601,14 +722,13 @@ impl EventLoop {
|
|
|
601
722
|
self.writer_rem(token)
|
|
602
723
|
}
|
|
603
724
|
|
|
604
|
-
fn _sig_add(&self, py: Python, sig:
|
|
605
|
-
let args = PyTuple::empty(py).into_pyobject(py)?.into_any().unbind();
|
|
725
|
+
fn _sig_add(&self, py: Python, sig: u8, callback: PyObject, args: PyObject, context: PyObject) -> Result<()> {
|
|
606
726
|
let handle = Py::new(py, CBHandle::new(callback, args, context))?;
|
|
607
727
|
self.sig_handlers.insert(sig, handle);
|
|
608
728
|
Ok(())
|
|
609
729
|
}
|
|
610
730
|
|
|
611
|
-
fn _sig_rem(&self, sig:
|
|
731
|
+
fn _sig_rem(&self, sig: u8) -> bool {
|
|
612
732
|
self.sig_handlers.remove(&sig).is_some()
|
|
613
733
|
}
|
|
614
734
|
|
|
@@ -616,26 +736,6 @@ impl EventLoop {
|
|
|
616
736
|
self.sig_handlers.clear();
|
|
617
737
|
}
|
|
618
738
|
|
|
619
|
-
fn _sig_handle(&self, py: Python, sig: u16) -> bool {
|
|
620
|
-
if let Some(handle) = self.sig_handlers.get(&sig) {
|
|
621
|
-
handle.get().run(py);
|
|
622
|
-
return true;
|
|
623
|
-
}
|
|
624
|
-
false
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
fn _sig_ceval(&self, noop: PyObject) {
|
|
628
|
-
let noop_ptr = noop.as_ptr();
|
|
629
|
-
unsafe {
|
|
630
|
-
pyo3::ffi::PyErr_CheckSignals();
|
|
631
|
-
pyo3::ffi::compat::PyObject_CallNoArgs(noop_ptr);
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
fn _wake(&self) {
|
|
636
|
-
self.wake();
|
|
637
|
-
}
|
|
638
|
-
|
|
639
739
|
fn _run(&self, py: Python) -> PyResult<()> {
|
|
640
740
|
loop {
|
|
641
741
|
if self.stopping.load(atomic::Ordering::Relaxed) {
|
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
#[cfg(not(any(target_os = "freebsd", target_os = "windows")))]
|
|
2
|
-
#[global_allocator]
|
|
3
|
-
static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
|
|
4
|
-
|
|
5
|
-
#[cfg(any(target_os = "freebsd", target_os = "windows"))]
|
|
6
|
-
#[global_allocator]
|
|
7
|
-
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
|
|
8
|
-
|
|
9
1
|
use pyo3::prelude::*;
|
|
10
2
|
use std::sync::OnceLock;
|
|
11
3
|
|
|
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
|