Since this is most likely an XY problem, I will provide you with more background.
I am developing a library that starts a tokio::net::TcpListener
, waits for incoming connections and processes them.
I have implemented a signal handler in a separate thread that catches SIGTERM/SIGINT and initiates a shutdown procedure:
tokio::select! {
_ = sigterm.recv() => {
println!("Received SIGTERM.");
}
_ = sigint.recv() => {
println!("Received SIGINT.");
}
};
// shutdown_server_tx.send(()) ....
When I build a binary instead of a library, run the application, and press CTRL+C, everything works as expected (signal catch and shutdown procedure are executed).
However, instead of building a standalone binary, I want to integrate my Rust code (as a lib) into existing C++ code. I have already created the pub extern "C" fn
function and checked that I can correctly call it in C++. Obviously, when building the C++ code and starting the application, the signal is not passed onto my Rust code. This is a problem, because the shutdown routine implemented in Rust will not be executed.
I thought that I can address this issue by creating a tokio::sync::oneshot::channel()
in my Rust application and add the receiver to the tokio::select!
part. This definitely works, but the problem is that I do not know how to call the sender from C++.
This is what I tried:
lazy_static! {
pub static ref SH_TX_RX: (Sender<()>, Receiver<()>) = oneshot::channel();
}
#[no_mangle]
pub extern "C" fn run() {
println!("Starting server...");
match srv::MyServer::new(SH_TX_RX.1) {
Ok(server) => match server.run() {
Ok(_) => {}
Err(e) => {
error!("Error: {:?}", e);
}
},
Err(e) => {
// ...
}
}
println!("Exiting...");
}
#[no_mangle]
pub extern "C" fn exit() {
let sender = &SH_TX_RX.0;
sender.send(());
()
}
I thought that it needs to be static, because I cannot keep a pointer to MyServer
in my C++ code. However, I get the following compiler errors:
error[E0507]: cannot move out of dereference of `SH_TX_RX`
--> src/lib.rs:35:47
|
35 | match srv::MyServer::new(SHUTDOWN.1) {
| ^^^^^^^^^^ move occurs because value has type `tokio::sync::oneshot::Receiver<()>`, which does not implement the `Copy` trait
error[E0507]: cannot move out of `*sender` which is behind a shared reference
--> src/lib.rs:60:5
|
60 | sender.send(());
| ^^^^^^^^^^^^^^^ move occurs because `*sender` has type `tokio::sync::oneshot::Sender<()>`, which does not implement the `Copy` trait