Are there any general rules, design documentation or something similar that explains how the Rust standard library deals with threads that were not spawned by std::thread
?
I have a cdylib
crate and want to use it from another language in a threaded manner:
use std::mem;
use std::sync::{Arc, Mutex};
use std::thread;
type jlong = usize;
type SharedData = Arc<Mutex<u32>>;
struct Foo {
data: SharedData,
}
#[no_mangle]
pub fn Java_com_example_Foo_init(shared_data: &SharedData) -> jlong {
let this = Box::into_raw(Box::new(Foo { data: shared_data.clone() }));
this as jlong
}
#[cfg(target_pointer_width = "32")]
unsafe fn jlong_to_pointer<T>(val: jlong) -> *mut T {
mem::transmute::<u32, *mut T>(val as u32)
}
#[cfg(target_pointer_width = "64")]
unsafe fn jlong_to_pointer<T>(val: jlong) -> *mut T {
mem::transmute::<jlong, *mut T>(val)
}
#[no_mangle]
pub fn Java_com_example_Foo_f(this: jlong) {
let mut this = unsafe { jlong_to_pointer::<Foo>(this).as_mut().unwrap() };
let data = this.data.clone();
let mut data = data.lock().unwrap();
*data = *data + 5;
}
specifically in
let shared_data = Arc::new(Mutex::new(5));
let foo = Java_com_example_Foo_init(&shared_data);
is it safe to modify shared_data
from a thread spawned by thread::spawn
if Java_com_example_Foo_f
will be called from an unknown JVM thread?
Yes. The issue you linked relates to librustrt
, which was removed before Rust 1.0. RFC 230 , which removed librustrt
, specifically notes:
When embedding Rust code into other contexts -- whether calling from C code or embedding in high-level languages -- there is a fair amount of setup needed to provide the "runtime" infrastructure that
libstd
relies on. Iflibstd
was instead bound to the native threading and I/O system, the embedding setup would be much simpler.
Additionally, see PR #19654 which implemented that RFC:
When using Rust in an embedded context, it should now be possible to call a Rust function directly as a C function with absolutely no setup, though in that case panics will cause the process to abort. In this regard, the C/Rust interface will look much like the C/C++ interface.
For current documentation, the Rustonomicon chapter on FFI 's examples of Rust code to be called from C make use of libstd
(including Mutex
, I believe, though that's an implementation detail of println
) without any caveats relating to runtime setup.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.