lora-ruby 0.5.6 → 0.8.4
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.
- checksums.yaml +4 -4
- data/README.md +54 -11
- data/extconf.rb +1 -1
- data/lib/lora_ruby/types.rb +17 -1
- data/lib/lora_ruby/version.rb +1 -1
- data/lib/lora_ruby.rb +2 -2
- data/src/errors.rs +74 -0
- data/src/from_ruby.rs +419 -0
- data/src/gvl.rs +55 -0
- data/src/lib.rs +266 -559
- data/src/to_ruby.rs +243 -0
- metadata +8 -4
data/src/gvl.rs
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
//! Global VM Lock release primitive.
|
|
2
|
+
|
|
3
|
+
use std::ffi::c_void;
|
|
4
|
+
use std::mem::MaybeUninit;
|
|
5
|
+
|
|
6
|
+
/// Run `f` with Ruby's Global VM Lock released.
|
|
7
|
+
///
|
|
8
|
+
/// Semantics match `rb_thread_call_without_gvl` — other Ruby threads can
|
|
9
|
+
/// progress while `f` runs. The closure MUST NOT touch Ruby state (no
|
|
10
|
+
/// `Value`s, no allocations into the Ruby heap), which we arrange by
|
|
11
|
+
/// keeping all such work on the calling thread. Everything inside
|
|
12
|
+
/// `database_execute`'s closure is pure Rust on pre-extracted data, so
|
|
13
|
+
/// this is sound.
|
|
14
|
+
pub(crate) fn without_gvl<F, R>(f: F) -> R
|
|
15
|
+
where
|
|
16
|
+
F: FnOnce() -> R,
|
|
17
|
+
F: Send,
|
|
18
|
+
R: Send,
|
|
19
|
+
{
|
|
20
|
+
struct Data<F, R> {
|
|
21
|
+
func: Option<F>,
|
|
22
|
+
result: MaybeUninit<R>,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
unsafe extern "C" fn trampoline<F, R>(data: *mut c_void) -> *mut c_void
|
|
26
|
+
where
|
|
27
|
+
F: FnOnce() -> R,
|
|
28
|
+
{
|
|
29
|
+
let data = &mut *(data as *mut Data<F, R>);
|
|
30
|
+
let f = data
|
|
31
|
+
.func
|
|
32
|
+
.take()
|
|
33
|
+
.expect("without_gvl: closure already taken");
|
|
34
|
+
data.result.write(f());
|
|
35
|
+
std::ptr::null_mut()
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
let mut data = Data::<F, R> {
|
|
39
|
+
func: Some(f),
|
|
40
|
+
result: MaybeUninit::uninit(),
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
unsafe {
|
|
44
|
+
rb_sys::rb_thread_call_without_gvl(
|
|
45
|
+
Some(trampoline::<F, R>),
|
|
46
|
+
&mut data as *mut _ as *mut c_void,
|
|
47
|
+
// No unblock function — the engine doesn't implement
|
|
48
|
+
// cooperative cancellation, and a forced longjmp out of a
|
|
49
|
+
// mutex-holding section would be worse than waiting.
|
|
50
|
+
None,
|
|
51
|
+
std::ptr::null_mut(),
|
|
52
|
+
);
|
|
53
|
+
data.result.assume_init()
|
|
54
|
+
}
|
|
55
|
+
}
|