Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle long running external function calls such as blocking I/O in Rust?

Tags:

io

rust

task

ffi

Editor's note: This question is from a version of Rust prior to 1.0 and uses terms and functions that do not exist in Rust 1.0 code. The concepts expressed are still relevant.

I need to read data provided by an external process via a POSIX file descriptor in my Rust program. The file descriptor connection is kept up a very long time (hours) and the other side passes data to me from time to time. I need to read and process the data stream continuously.

To do so, I wrote a loop that calls libc::read() (readv actually) to read the data and processes it when received. Since this would block the whole scheduler, I'm spawning a task on a new scheduler (task::spawn_sched(SingleThreaded)). This works fine as long as it runs, but I can't find a way to cleanly shut down the loop.

Since the loop is blocking most of the time, I can't use a port/channel to notify the loop to exit.

I tried to kill the loop task by taking it down using a failing linked task (spawn the loop task supervised, spawn a linked task within it and wait for a signal on a port to happen before fail!()ing and taking down the loop task with it). It works well in tests, but the libc::read() isn't interrupted (the task doesn't fail before read finishes and it hits task::yield() at some time.

I learned a lot looking at libcore sources, but I can't seem to find a proper solution.

  1. Is there a way to kill a (child) task in Rust even if it's doing some long external function call like a blocking read?
  2. Is there a way to do non-blocking reads on a POSIX file descriptor so that Rust keeps control over the task?
  3. How can I react to signals, e.g. SIGTERMif the user terminates my program? There doesn't seem to be something like sigaction() in Rust yet.
like image 561
Zargony Avatar asked May 29 '13 15:05

Zargony


1 Answers

  1. According to mozila, killing a task is no more possible, for now, let alone blocking read.
  2. It will be possible to do so after mozilla/rust/pull/11410, see also my other issue report for rust-zmq erickt/rust-zmq/issues/24 which also depends on this. (sorry about the links)
  3. Maybe the signal listener will work for you.
like image 52
Fantix King Avatar answered Sep 23 '22 10:09

Fantix King