diff --git a/examples/notify_inval_entry.rs b/examples/notify_inval_entry.rs index cd017e26..51d0eb4e 100644 --- a/examples/notify_inval_entry.rs +++ b/examples/notify_inval_entry.rs @@ -164,7 +164,7 @@ fn main() { let session = fuser::Session::new(fs, opts.mount_point, &options).unwrap(); let notifier = session.notifier(); - let _bg = session.spawn().unwrap(); + let _bg = session.spawn(); loop { let mut fname = fname.lock().unwrap(); diff --git a/examples/notify_inval_inode.rs b/examples/notify_inval_inode.rs index d7ab155c..51f09004 100644 --- a/examples/notify_inval_inode.rs +++ b/examples/notify_inval_inode.rs @@ -202,7 +202,7 @@ fn main() { let session = fuser::Session::new(fs, opts.mount_point, &options).unwrap(); let notifier = session.notifier(); - let _bg = session.spawn().unwrap(); + let _bg = session.spawn(); loop { let mut s = fdata.lock().unwrap(); diff --git a/examples/poll.rs b/examples/poll.rs index aebdf5b5..ad5bcfa8 100644 --- a/examples/poll.rs +++ b/examples/poll.rs @@ -338,7 +338,7 @@ fn main() { let mntpt = std::env::args().nth(1).unwrap(); let session = fuser::Session::new(fs, mntpt, &options).unwrap(); - let bg = session.spawn().unwrap(); + let bg = session.spawn(); producer(&data, &bg.notifier()); } diff --git a/src/lib.rs b/src/lib.rs index 4885f387..96acf9c5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1012,8 +1012,7 @@ pub fn spawn_mount<'a, FS: Filesystem + Send + 'static + 'a, P: AsRef>( .map(|x| Some(MountOption::from_str(x.to_str()?))) .collect(); let options = options.ok_or(ErrorKind::InvalidData)?; - Session::new(filesystem, mountpoint.as_ref(), options.as_ref()) - .and_then(session::Session::spawn) + Session::new(filesystem, mountpoint.as_ref(), options.as_ref()).map(session::Session::spawn) } /// Mount the given filesystem to the given mountpoint. This function spawns @@ -1031,5 +1030,5 @@ pub fn spawn_mount2<'a, FS: Filesystem + Send + 'static + 'a, P: AsRef>( options: &[MountOption], ) -> io::Result { check_option_conflicts(options)?; - Session::new(filesystem, mountpoint.as_ref(), options).and_then(session::Session::spawn) + Session::new(filesystem, mountpoint.as_ref(), options).map(session::Session::spawn) } diff --git a/src/session.rs b/src/session.rs index e1393a2d..410b669a 100644 --- a/src/session.rs +++ b/src/session.rs @@ -178,7 +178,12 @@ impl Session { /// Unmount the filesystem pub fn unmount(&mut self) { - drop(std::mem::take(&mut *self.mount.lock().unwrap())); + drop(std::mem::take(&mut *self.mount.lock().unwrap_or_else( + |poisoned| { + warn!("Ignored poisoned mount lock"); + poisoned.into_inner() + }, + ))); } /// Returns a thread-safe object that can be used to unmount the Filesystem @@ -202,9 +207,13 @@ pub struct SessionUnmounter { impl SessionUnmounter { /// Unmount the filesystem - pub fn unmount(&mut self) -> io::Result<()> { - drop(std::mem::take(&mut *self.mount.lock().unwrap())); - Ok(()) + pub fn unmount(&mut self) { + drop(std::mem::take(&mut *self.mount.lock().unwrap_or_else( + |poisoned| { + warn!("Ignored poisoned mount lock"); + poisoned.into_inner() + }, + ))); } } @@ -219,7 +228,7 @@ fn aligned_sub_buf(buf: &mut [u8], alignment: usize) -> &mut [u8] { impl Session { /// Run the session loop in a background thread - pub fn spawn(self) -> io::Result { + pub fn spawn(self) -> BackgroundSession { BackgroundSession::new(self) } } @@ -231,7 +240,12 @@ impl Drop for Session { self.destroyed = true; } - if let Some((mountpoint, _mount)) = std::mem::take(&mut *self.mount.lock().unwrap()) { + if let Some((mountpoint, _mount)) = + std::mem::take(&mut *self.mount.lock().unwrap_or_else(|poisoned| { + warn!("Ignored poisoned mount lock"); + poisoned.into_inner() + })) + { info!("unmounting session at {}", mountpoint.display()); } } @@ -251,19 +265,23 @@ impl BackgroundSession { /// Create a new background session for the given session by running its /// session loop in a background thread. If the returned handle is dropped, /// the filesystem is unmounted and the given session ends. - pub fn new(se: Session) -> io::Result { + pub fn new(se: Session) -> BackgroundSession { let sender = se.ch.sender(); // Take the fuse_session, so that we can unmount it - let mount = std::mem::take(&mut *se.mount.lock().unwrap()).map(|(_, mount)| mount); + let mount = std::mem::take(&mut *se.mount.lock().unwrap_or_else(|poisoned| { + warn!("Ignored poisoned mount lock"); + poisoned.into_inner() + })) + .map(|(_, mount)| mount); let guard = thread::spawn(move || { let mut se = se; se.run() }); - Ok(BackgroundSession { + BackgroundSession { guard, sender, _mount: mount, - }) + } } /// Unmount the filesystem and join the background thread. /// # Panics diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs index a351d4dd..3effd7f1 100644 --- a/tests/integration_tests.rs +++ b/tests/integration_tests.rs @@ -18,7 +18,7 @@ fn unmount_no_send() { let mut unmounter = session.unmount_callable(); thread::spawn(move || { thread::sleep(Duration::from_secs(1)); - unmounter.unmount().unwrap(); + unmounter.unmount(); }); session.run().unwrap(); }