Trying to shutdown my Tokio Runtime from C

Hi all,

I'm new to Tokio and have everything working that I'd like, but trying to shutdown gracefully. I'm using a oneshot::channel to send a message to my Runtime to shutdown. Calling my shutdown routing from C. That's all working, but I think I'm fighting with my lack of Rust fundamentals.

I'm getting:

Cannot move 
cannot move out of an `Arc` [E0507] move occurs because value has type `tokio::runtime::Runtime`, which does not implement the `Copy` trait Note: `tokio::runtime::Runtime::shutdown_background` takes ownership of the receiver `self`, which moves value

as I'm fighting with moves and saw Runtime in tokio::runtime - Rust

Here's my code:

The docs are great, and I was trying to use Cancellation Tokens too, but there's so much missing for a newbie to Tokio in places like // ... spawn application as separate task ... and // send shutdown signal to application and wait:

use tokio::signal;
use tokio::sync::mpsc;

#[tokio::main]
async fn main() {
    let (shutdown_send, mut shutdown_recv) = mpsc::unbounded_channel();

    // ... spawn application as separate task ...
    //
    // application uses shutdown_send in case a shutdown was issued from inside
    // the application

    tokio::select! {
        _ = signal::ctrl_c() => {},
        _ = shutdown_recv.recv() => {},
    }

    // send shutdown signal to application and wait
}

My full function is here, which needs a bit of tidy up:

Maybe my next step is to create a tiny demo / reduced example.

Thanks.

Didn't need Arc. Read the docs again and saw the fact I can do:

inner_runtime.shutdown_background();

All good now!

Hmm, looks like I'm creating two runtimes then:

(gdb) i thr
  Id   Target Id                                            Frame 
* 1    Thread 0x7ffff620abc0 (LWP 357235) "sentrypeer"      0x00007ffff76f2c13 in clock_nanosleep@GLIBC_2.2.5 () from /lib64/libc.so.6
  2    Thread 0x7ffff58006c0 (LWP 357239) "MHD-listen"      0x00007ffff7727e57 in select () from /lib64/libc.so.6
  3    Thread 0x7ffff4e006c0 (LWP 357240) "sip_daemon"      0x00007ffff7727e57 in select () from /lib64/libc.so.6
  4    Thread 0x7ffff44006c0 (LWP 357241) "tls_tokio_runti" 0x00007ffff772aa32 in epoll_wait () from /lib64/libc.so.6
  5    Thread 0x7fffefe006c0 (LWP 357242) "tls_tokio_runti" 0x00007ffff77283dd in syscall () from /lib64/libc.so.6
  6    Thread 0x7fffefa006c0 (LWP 357243) "tls_tokio_runti" 0x00007ffff77283dd in syscall () from /lib64/libc.so.6
  7    Thread 0x7fffef6006c0 (LWP 357244) "tls_tokio_runti" 0x00007ffff77283dd in syscall () from /lib64/libc.so.6
  8    Thread 0x7fffef2006c0 (LWP 357245) "tls_tokio_runti" 0x00007ffff77283dd in syscall () from /lib64/libc.so.6
  9    Thread 0x7fffeee006c0 (LWP 357246) "tls_tokio_runti" 0x00007ffff77283dd in syscall () from /lib64/libc.so.6
  10   Thread 0x7fffeea006c0 (LWP 357247) "tls_tokio_runti" 0x00007ffff77283dd in syscall () from /lib64/libc.so.6
  11   Thread 0x7fffee6006c0 (LWP 357248) "tls_tokio_runti" 0x00007ffff77283dd in syscall () from /lib64/libc.so.6
  12   Thread 0x7fffee2006c0 (LWP 357249) "tls_tokio_runti" 0x00007ffff77283dd in syscall () from /lib64/libc.so.6
  13   Thread 0x7fffede006c0 (LWP 357250) "tls_tokio_runti" 0x00007ffff77283dd in syscall () from /lib64/libc.so.6
  14   Thread 0x7fffeda006c0 (LWP 357251) "tls_tokio_runti" 0x00007ffff77283dd in syscall () from /lib64/libc.so.6
  15   Thread 0x7fffed6006c0 (LWP 357252) "tls_tokio_runti" 0x00007ffff77283dd in syscall () from /lib64/libc.so.6
  16   Thread 0x7fffed2006c0 (LWP 357253) "tls_std_thread"  0x00007ffff77283dd in syscall () from /lib64/libc.so.6
  17   Thread 0x7fffece006c0 (LWP 357254) "tokio-runtime-w" 0x00007ffff772aa32 in epoll_wait () from /lib64/libc.so.6
  18   Thread 0x7fffeca006c0 (LWP 357255) "tokio-runtime-w" 0x00007ffff77283dd in syscall () from /lib64/libc.so.6
  19   Thread 0x7fffec6006c0 (LWP 357256) "tokio-runtime-w" 0x00007ffff77283dd in syscall () from /lib64/libc.so.6
  20   Thread 0x7fffe3e006c0 (LWP 357257) "tokio-runtime-w" 0x00007ffff77283dd in syscall () from /lib64/libc.so.6
  21   Thread 0x7fffe3a006c0 (LWP 357258) "tokio-runtime-w" 0x00007ffff77283dd in syscall () from /lib64/libc.so.6
  22   Thread 0x7fffe36006c0 (LWP 357259) "tokio-runtime-w" 0x00007ffff77283dd in syscall () from /lib64/libc.so.6
  23   Thread 0x7fffe32006c0 (LWP 357260) "tokio-runtime-w" 0x00007ffff77283dd in syscall () from /lib64/libc.so.6
  24   Thread 0x7fffe2e006c0 (LWP 357261) "tokio-runtime-w" 0x00007ffff77283dd in syscall () from /lib64/libc.so.6
  25   Thread 0x7fffe2a006c0 (LWP 357262) "tokio-runtime-w" 0x00007ffff77283dd in syscall () from /lib64/libc.so.6
  26   Thread 0x7fffe26006c0 (LWP 357263) "tokio-runtime-w" 0x00007ffff77283dd in syscall () from /lib64/libc.so.6
  27   Thread 0x7fffe22006c0 (LWP 357264) "tokio-runtime-w" 0x00007ffff77283dd in syscall () from /lib64/libc.so.6
  28   Thread 0x7fffe1e006c0 (LWP 357265) "tokio-runtime-w" 0x00007ffff77283dd in syscall () from /lib64/libc.so.6

So the solution for my future self, and others was to:

    let rt = tokio::runtime::Builder::new_multi_thread()
        .thread_name("tls_tokio_runtime")
        .enable_all()
        .build()
        .unwrap();
    let handle = rt.handle().clone();

then use that handle instead of rt:

    let _std_thread_handle = thread_builder.spawn(move || {
        handle.block_on(async move {
            let config = config_from_env().unwrap();

then I can use rt later as planned whilst listening for a oneshot message to shutdown trigger by the other side of the FFI:

            match rx.await {
                Ok(msg) => {
                    if debug_mode || verbose_mode {
                        eprintln!("Tokio received a oneshot message to shutdown: {:?}", msg);
                    }
                    // https://docs.rs/tokio/latest/tokio/runtime/struct.Runtime.html#method.shutdown_background
                    rt.shutdown_background();
                    libc::EXIT_SUCCESS
                }
                Err(_) => {
                    eprintln!("Failed to receive message to shutdown.");
                    libc::EXIT_FAILURE
                }
            }

Full version here - SentryPeer/sentrypeer_rust/src/tls.rs at main · SentryPeer/SentryPeer · GitHub

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.