Repository: astral-sh/uv
File: crates/uv-fs/src/lib.rs (Rust)

Code before:
                Ok(Self(file))
            }
        }
    }

    /// Inner implementation for [`LockedFile::acquire_no_wait`].
    fn lock_file_no_wait(file: fs_err::File, resource: &str) -> Option<Self> {
        trace!(
            "Checking lock for `{resource}` at `{}`",
            file.path().user_display()
        );
        match file.file().try_lock_exclusive() {
            Ok(()) => {
                debug!("Acquired lock for `{resource}`");
                Some(Self(file))
            }
            Err(err) => {
                // Log error code and enum kind to help debugging more exotic failures.
                if err.kind() != std::io::ErrorKind::WouldBlock {
                    debug!("Try lock error: {err:?}");
                }
                debug!("Lock is busy for `{resource}`");
                None
            }
        }
    }

    /// Inner implementation for [`LockedFile::acquire_shared_blocking`] and
    /// [`LockedFile::acquire_blocking`].
    fn lock_file_shared_blocking(
        file: fs_err::File,
        resource: &str,
    ) -> Result<Self, std::io::Error> {
        trace!(
            "Checking shared lock for `{resource}` at `{}`",
            file.path().user_display()
        );
        // TODO(konsti): Update fs_err to support this.
        match FileExt::try_lock_shared(file.file()) {
            Ok(()) => {
                debug!("Acquired shared lock for `{resource}`");
                Ok(Self(file))
            }
            Err(err) => {
                // Log error code and enum kind to help debugging more exotic failures.
                if err.kind() != std::io::ErrorKind::WouldBlock {
                    debug!("Try lock error: {err:?}");
                }
                info!(
                    "Waiting to acquire shared lock for `{resource}` at `{}`",
                    file.path().user_display(),

Review comment (suggestion):
We should loop on `EINTR`, and probably in the blocking cases too, unless I'm missing something that already does that.

Code after:
                info!(
                    "Waiting to acquire lock for `{resource}` at `{}`",
                    file.path().user_display(),
                );
                file.file().lock_exclusive().map_err(|err| {
                    // Not an fs_err method, we need to build our own path context
                    std::io::Error::other(format!(
                        "Could not acquire lock for `{resource}` at `{}`: {}",
                        file.path().user_display(),
                        err
                    ))
                })?;

                debug!("Acquired lock for `{resource}`");
                Ok(Self(file))
            }
        }
    }

    /// Inner implementation for [`LockedFile::acquire_no_wait`].
    fn lock_file_no_wait(file: fs_err::File, resource: &str) -> Option<Self> {
        trace!(
            "Checking lock for `{resource}` at `{}`",
            file.path().user_display()
        );
        match file.file().try_lock_exclusive() {
            Ok(()) => {
                debug!("Acquired lock for `{resource}`");
                Some(Self(file))
            }
            Err(err) => {
                // Log error code and enum kind to help debugging more exotic failures.
                if !is_known_already_locked_error(&err) {
                    debug!("Try lock error: {err:?}");
                }
                debug!("Lock is busy for `{resource}`");
                None
            }
        }
    }

    /// Inner implementation for [`LockedFile::acquire_shared_blocking`] and
    /// [`LockedFile::acquire_blocking`].
    fn lock_file_shared_blocking(
        file: fs_err::File,
        resource: &str,
    ) -> Result<Self, std::io::Error> {
        trace!(
            "Checking shared lock for `{resource}` at `{}`",
            file.path().user_display()
        );