@@ -87,13 +87,23 @@ mod common {
87
87
}
88
88
89
89
#[ 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 ;
92
94
93
95
pub struct ThreadCTX {
94
96
interner : * mut jrsonnet_interner:: interop:: PoolState ,
95
97
gc : * mut jrsonnet_gcmodule:: interop:: GcState ,
96
98
}
99
+ impl ThreadCTX {
100
+ pub fn invalid ( ) -> Self {
101
+ Self {
102
+ interner : null_mut ( ) ,
103
+ gc : null_mut ( ) ,
104
+ }
105
+ }
106
+ }
97
107
98
108
/// Golang jrsonnet bindings require Jsonnet VM to be movable.
99
109
/// Jrsonnet uses `thread_local` in some places, thus making VM
@@ -106,25 +116,20 @@ mod threading {
106
116
/// Current thread GC will be broken after this call, need to call
107
117
/// `jrsonet_enter_thread` before doing anything.
108
118
#[ 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 {
111
121
interner : jrsonnet_interner:: interop:: exit_thread ( ) ,
112
122
gc : unsafe { jrsonnet_gcmodule:: interop:: exit_thread ( ) } ,
113
- } ) )
123
+ } ) ) )
114
124
}
115
125
116
126
#[ 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) } ;
123
131
unsafe { jrsonnet_interner:: interop:: reenter_thread ( ctx. interner ) }
124
132
unsafe { jrsonnet_gcmodule:: interop:: reenter_thread ( ctx. gc ) }
125
- // Just in case
126
- ctx. interner = null_mut ( ) ;
127
- ctx. gc = null_mut ( ) ;
128
133
}
129
134
130
135
// ThreadId is compatible with u64, and there is unstable cast
0 commit comments