fn drop()

in src/concurrent.rs [91:128]


    fn drop(&mut self) {
        debug!("Closing ShareableFile with fd {}", self.fd);

        // We are about to touch file handles used by other threads.  If those threads are blocked
        // on a select call, the call may return an error on some systems due to the closed file
        // descriptors.  If those threads are about to issue a read after a select, the read will
        // fail with a bad file descriptor.  Prepare them about these potential failure conditions
        // before we actually touch anything.
        self.closed.store(true, Ordering::SeqCst);

        for watcher in &self.watchers {
            if let Err(e) = unistd::write(*watcher, &[0]) {
                // This write to a pipe we control really should not have failed.  If it did there
                // is not much we can do other than log an error.  We may get stuck threads on exit
                // though...
                //
                // TODO(jmmv): We expect the write to fail if we had any ShareableFileReader that
                // has already been dropped, as that drop would have closed the read end of the
                // pipe.  Note that this means that, if we create/drop ShareableFileReaders non-stop
                // for this ShareableFile, we'll exhaust the open file descriptors because we are
                // leaking the write ends of these pipes.  This should be fixed, but it's not a big
                // deal because we don't do this in sandboxfs.
                if e.as_errno().expect("Must have been a system error") != Errno::EPIPE {
                    warn!("Failed to tell ShareableFileReader with handle {} of close: {}",
                        *watcher, e)
                }
            }
            if let Err(e) = unistd::close(*watcher) {
                // Closing should really not have failed, but if it did, it does not hurt and there
                // is nothing we can do anyway.
                warn!("Failed to close pipe write end with handle {}: {}", *watcher, e)
            }
        }

        if let Err(e) = unistd::close(self.fd) {
            warn!("Failed to close fd {}: {}", self.fd, e);
        }
    }