nix-rust / nix

Rust friendly bindings to *nix APIs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

FdSet is difficulty to use

ensc opened this issue · comments

Code like

use nix::sys::{ select, signalfd::{self, SigSet} };
fn main() {
    let mut fd_sig = signalfd::SignalFd::new(&SigSet::empty()).unwrap();
    let mut fd_tmp = signalfd::SignalFd::new(&SigSet::empty()).unwrap();

    loop {
	let mut fdset = select::FdSet::new();

	fdset.insert(&fd_tmp);
	fdset.insert(&fd_sig);

	select::select(None, &mut fdset, None, None, None).unwrap();

	if fdset.contains(&fd_sig) {
	    fd_sig.read_signal().unwrap();
	}

	if fdset.contains(&fd_tmp) {
	}
    }
}

fails to compile with

error[E0502]: cannot borrow `fd_sig` as mutable because it is also borrowed as immutable
  --> src/main.rs:17:6
   |
12 |     fdset.insert(&fd_sig);
   |                  ------- immutable borrow occurs here
...
17 |         fd_sig.read_signal().unwrap();
   |         ^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
...
20 |     if fdset.contains(&fd_tmp) {
   |        ----- immutable borrow later used here

Workaround is to store results of all used fdset.contains() in temporary variables like

        ...
	select::select(None, &mut fdset, None, None, None).unwrap();

        let ev_sig = fdset.contains(&fd_sig);
        let ev_tmp = fdset.contains(&fd_tmp);

But this is ugly.

Would it be possible to change the FdSet functions to

-    pub fn insert<Fd: AsFd>(&mut self, fd: &'fd Fd) {
+    pub fn insert<Fd: AsFd + 'fd>(&mut self, fd: Fd) {

?

Yes, your analysis is correct. Would you care to submit a PR?