Skip to content

Commit e868421

Browse files
committed
feat: dumb thread-safe implementation
1 parent ca50bd2 commit e868421

File tree

9 files changed

+705
-307
lines changed

9 files changed

+705
-307
lines changed

Cargo.lock

+78
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bindings/jsonnet/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ jrsonnet-parser.workspace = true
2424
jrsonnet-stdlib.workspace = true
2525
jrsonnet-gcmodule.workspace = true
2626
jrsonnet-interner.workspace = true
27+
crossbeam = { version = "0.8.4", features = ["crossbeam-channel"] }
28+
rayon = "1.10.0"
2729

2830
[lib]
2931
name = "jsonnet"

bindings/jsonnet/src/interop.rs

+19-14
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,23 @@ mod common {
8787
}
8888

8989
#[cfg(feature = "interop-threading")]
90-
mod threading {
91-
use std::{ffi::c_int, thread::ThreadId};
90+
pub mod threading {
91+
use std::{ffi::c_int, ptr::null_mut, sync::atomic::AtomicPtr, thread::ThreadId};
92+
93+
use crossbeam::atomic::AtomicConsume;
9294

9395
pub struct ThreadCTX {
9496
interner: *mut jrsonnet_interner::interop::PoolState,
9597
gc: *mut jrsonnet_gcmodule::interop::GcState,
9698
}
99+
impl ThreadCTX {
100+
pub fn invalid() -> Self {
101+
Self {
102+
interner: null_mut(),
103+
gc: null_mut(),
104+
}
105+
}
106+
}
97107

98108
/// Golang jrsonnet bindings require Jsonnet VM to be movable.
99109
/// Jrsonnet uses `thread_local` in some places, thus making VM
@@ -106,25 +116,20 @@ mod threading {
106116
/// Current thread GC will be broken after this call, need to call
107117
/// `jrsonet_enter_thread` before doing anything.
108118
#[no_mangle]
109-
pub unsafe extern "C" fn jrsonnet_exit_thread() -> *mut ThreadCTX {
110-
Box::into_raw(Box::new(ThreadCTX {
119+
pub unsafe extern "C" fn jrsonnet_exit_thread() -> AtomicPtr<ThreadCTX> {
120+
AtomicPtr::new(Box::into_raw(Box::new(ThreadCTX {
111121
interner: jrsonnet_interner::interop::exit_thread(),
112122
gc: unsafe { jrsonnet_gcmodule::interop::exit_thread() },
113-
}))
123+
})))
114124
}
115125

116126
#[no_mangle]
117-
pub extern "C" fn jrsonnet_reenter_thread(mut ctx: Box<ThreadCTX>) {
118-
use std::ptr::null_mut;
119-
assert!(
120-
!ctx.interner.is_null() && !ctx.gc.is_null(),
121-
"reused context?"
122-
);
127+
pub extern "C" fn jrsonnet_reenter_thread(ctx: AtomicPtr<ThreadCTX>) {
128+
let ctx = ctx.load_consume();
129+
assert!(!ctx.is_null(), "reused context?");
130+
let ctx = unsafe { Box::from_raw(ctx) };
123131
unsafe { jrsonnet_interner::interop::reenter_thread(ctx.interner) }
124132
unsafe { jrsonnet_gcmodule::interop::reenter_thread(ctx.gc) }
125-
// Just in case
126-
ctx.interner = null_mut();
127-
ctx.gc = null_mut();
128133
}
129134

130135
// ThreadId is compatible with u64, and there is unstable cast

0 commit comments

Comments
 (0)