You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm building a system that calls into C libraries. One of the libraries handles device initialisation. It returns a pointer, and cannot be called more than once. Hence the use of lazy_static.
I have two questions, one is about assuring how to constrain construction across the lifetime of a system, and another about the contracts that come with unsafe impl Send/Sync for $raw_ptr
Here is a code snippet of what I'm dealing with
// ../rustlibs/serial/src/lib.rs#![no_std]#[derive(Copy,Clone)]#[repr(C)]structSerialPtr(*const core::ffi::c_void);extern"C"{fnserial_send(c_library_struct:*const core::ffi::c_void, ...) -> usize;fnserial_init() -> SerialPtr;fnserial_register_handler(serial:SerialPtr, ...);}unsafeimpl core::marker::SendforSerial{}unsafeimpl core::marker::SyncforSerial{}pubstructSerial{ptr:SerialPtr}// essentially, SERIAL must be a singleton for the entire system due to serial_init call count.lazy_static!{static ref SERIAL:Serial = unsafe{let res = Serial{
ptr: serial_init(),// CRITICAL: must be called once, and once ONLY for entire system uptime};
serial_register_handler(res.ptr,Some(default_handler));
res
};}implSerial{pubfnsend(msg:&[u8]) -> usize{unsafe{serial_send(SERIAL.ptr, ...)}}
...
}
Here is the process flow of my system:
root-process start in C code-base (is always the first process after power-up, and last before power-down)
system initialisation from C code-base (not including serial_init)
spin up child process from C code-base(immediately sends request to root-process use of serial device. Blocks until root-process replys to request)
root-process calls into Rust code-base
root-proc recieves request from child
part of processing this uses Serial::send
For context of how I currently use it from the static library that C calls:
// ../rustlibs/root_service/src/lib.rs#![no_std]#[crate_type = "static_lib"]use serial::*;#[no_mangle]fnentry_point() -> ! {loop{matchblocking_recv(ipc_source, msg){// Derefs into SERIAL, thus init'ing the device on first match, replying with the resultSERIAL_SEND => reply(ipc_source,Serial::send(msg)),
...}}}
Regarding my question of limiting serial_init() invocation to once-only system wide: If I make serial a static lib, will that mean there will be a fresh serial_init() invoked for each executable that links it? Does the same apply if I make it an rlib? If I make it dylib, what would that do to duplicate SERIALs within system memory?
Regarding my question of marking Serial with Send + Sync, what can I do with respect to ensuring that it's safe?
The text was updated successfully, but these errors were encountered:
I'm building a system that calls into C libraries. One of the libraries handles device initialisation. It returns a pointer, and cannot be called more than once. Hence the use of lazy_static.
I have two questions, one is about assuring how to constrain construction across the lifetime of a system, and another about the contracts that come with
unsafe impl Send/Sync for $raw_ptr
Here is a code snippet of what I'm dealing with
Here is the process flow of my system:
Serial::send
For context of how I currently use it from the static library that C calls:
Regarding my question of limiting
serial_init()
invocation to once-only system wide: If I makeserial
a static lib, will that mean there will be a freshserial_init()
invoked for each executable that links it? Does the same apply if I make it anrlib
? If I make itdylib
, what would that do to duplicate SERIALs within system memory?Regarding my question of marking
Serial
withSend + Sync
, what can I do with respect to ensuring that it's safe?The text was updated successfully, but these errors were encountered: