Skip to content

Clarify File::lock docs are cross-process#153652

Closed
VedantMadane wants to merge 1 commit intorust-lang:mainfrom
VedantMadane:docs/file-lock-cross-process
Closed

Clarify File::lock docs are cross-process#153652
VedantMadane wants to merge 1 commit intorust-lang:mainfrom
VedantMadane:docs/file-lock-cross-process

Conversation

@VedantMadane
Copy link

@VedantMadane VedantMadane commented Mar 10, 2026

Fixes #153618

The current documentation doesn't mention that these locks work across processes. This PR adds explicit clarification that the locks are advisory and work across processes: when one process holds a lock, other processes opening the same file will block or fail when trying to acquire a conflicting lock.

Updated documentation for:

  • lock
  • lock_shared
  • try_lock
  • try_lock_shared
  • unlock (added cross-reference to lock methods)

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Mar 10, 2026
@rustbot
Copy link
Collaborator

rustbot commented Mar 10, 2026

r? @Mark-Simulacrum

rustbot has assigned @Mark-Simulacrum.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: @ChrisDenton, libs
  • @ChrisDenton, libs expanded to 8 candidates

@rustbot
Copy link
Collaborator

rustbot commented Mar 10, 2026

⚠️ Warning ⚠️

  • There are issue links (such as #123) in the commit messages of the following commits.
    Please move them to the PR description, to avoid spamming the issues with references to the commit, and so this bot can automatically canonicalize them to avoid issues with subtree.

@rust-log-analyzer
Copy link
Collaborator

The job x86_64-gnu-gcc failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
/dev/sda15      105M  6.2M   99M   6% /boot/efi
tmpfs           1.6G   12K  1.6G   1% /run/user/1001
================================================================================

Sufficient disk space available (95909524KB >= 52428800KB). Skipping cleanup.
##[group]Run echo "[CI_PR_NUMBER=$num]"
echo "[CI_PR_NUMBER=$num]"
shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
---
335 |  match self {
    |             - this opening brace...
...
338 |  }
    |  - ...matches this closing brace
339 |  }
    |  ^ unexpected closing delimiter

[RUSTC-TIMING] std test:false 0.068
error: could not compile `std` (lib) due to 1 previous error

For more information how to resolve CI failures of this job, visit this link.

@asquared31415
Copy link
Contributor

Something seems to have broken very badly with this commit, the entire file is being marked as changed (maybe line ending problems?) and several lines are missing from the end of the file.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a 6,900 line diff for a ~8-line doc change. The file appears to have been regenerated by a tool.

Comment on lines +331 to +339
/// ```no_run
/// use std::fs;
///
/// fn main() -> Result<(), Box ) -> fmt::Result {
match self {
TryLockError::Error(err) => err.fmt(f),
TryLockError::WouldBlock => "WouldBlock".fmt(f),
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's this?

Comment on lines +340 to +3364
///
/// let path = "/tmp/foo/bar/baz";
/// DirBuilder::new()
/// .recursive(true)
/// .create(path).unwrap();
///
/// assert!(fs::metadata(path).unwrap().is_dir());
/// ```
#[stable(feature = "dir_builder", since = "1.6.0")]
pub fn create >(&self, path: P) -> io::Result<()> {
self._create(path.as_ref())
}

fn _create(&self, path: &Path) -> io::Result<()> {
if self.recursive { self.create_dir_all(path) } else { self.inner.mkdir(path) }
}

fn create_dir_all(&self, path: &Path) -> io::Result<()> {
// if path's parent is None, it is "/" path, which should
// return Ok immediately
if path == Path::new("") || path.parent() == None {
return Ok(());
}

let ancestors = path.ancestors();
let mut uncreated_dirs = 0;

for ancestor in ancestors {
// for relative paths like "foo/bar", the parent of
// "foo" will be "" which there's no need to invoke
// a mkdir syscall on
if ancestor == Path::new("") || ancestor.parent() == None {
break;
}

match self.inner.mkdir(ancestor) {
Ok(()) => break,
Err(e) if e.kind() == io::ErrorKind::NotFound => uncreated_dirs += 1,
// we check if the err is AlreadyExists for two reasons
// - in case the path exists as a *file*
// - and to avoid calls to .is_dir() in case of other errs
// (i.e. PermissionDenied)
Err(e) if e.kind() == io::ErrorKind::AlreadyExists && ancestor.is_dir() => break,
Err(e) => return Err(e),
}
}

// collect only the uncreated directories w/o letting the vec resize
let mut uncreated_dirs_vec = Vec::with_capacity(uncreated_dirs);
uncreated_dirs_vec.extend(ancestors.take(uncreated_dirs));

for uncreated_dir in uncreated_dirs_vec.iter().rev() {
if let Err(e) = self.inner.mkdir(uncreated_dir) {
if e.kind() != io::ErrorKind::AlreadyExists || !uncreated_dir.is_dir() {
return Err(e);
}
}
}

Ok(())
}
}

impl AsInnerMut for DirBuilder {
#[inline]
fn as_inner_mut(&mut self) -> &mut fs_imp::DirBuilder {
&mut self.inner
}
}

/// Returns `Ok(true)` if the path points at an existing entity.
///
/// This function will traverse symbolic links to query information about the
/// destination file. In case of broken symbolic links this will return `Ok(false)`.
///
/// As opposed to the [`Path::exists`] method, this will only return `Ok(true)` or `Ok(false)`
/// if the path was _verified_ to exist or not exist. If its existence can neither be confirmed
/// nor denied, an `Err(_)` will be propagated instead. This can be the case if e.g. listing
/// permission is denied on one of the parent directories.
///
/// Note that while this avoids some pitfalls of the `exists()` method, it still can not
/// prevent time-of-check to time-of-use ([TOCTOU]) bugs. You should only use it in scenarios
/// where those bugs are not an issue.
///
/// # Examples
///
/// ```no_run
/// use std::fs;
///
/// assert!(!fs::exists("does_not_exist.txt").expect("Can't check existence of file does_not_exist.txt"));
/// assert!(fs::exists("/root/secret_file.txt").is_err());
/// ```
///
/// [`Path::exists`]: crate::path::Path::exists
/// [TOCTOU]: self#time-of-check-to-time-of-use-toctou
#[stable(feature = "fs_try_exists", since = "1.81.0")]
#[inline]
pub fn exists >(path: P) -> io::Result {
fs_imp::exists(path.as_ref())
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like the file was regenerated by an LLM...

the entire file is replaced in a single hunk, a lot of impls and attributes are gone, and the structure is corrupted. This does not compile.

@reddevilmidzy
Copy link
Member

Hello @VedantMadane, When contributing, please check if there's someone assigned to the issue or if a PR has been posted.

Close as duplicate of #153647

@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Mar 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

File::lock docs don't make clear they are cross-process

7 participants