Need some help for understanding memmap2 behaviour on Windows

Hi all,
I'm starting using memmap2 on windows and I have written the following tests:

use std::{path::Path, fs::{File, self}, io::Write};

use memmap2::MmapOptions;

static CONTENT: &str =
    "simple file content";

#[test]
pub fn simple_mmap_test() {
    let path = Path::new("c:\\temp\\lorem_ipsum.txt");
    let display = path.display();
    let mut file = match File::create(&path) {
        Err(why) => panic!("couldn't create {}: {}", display, why),
        Ok(file) => file,
    };
    match file.write_all(CONTENT.as_bytes()) {
        Err(why) => panic!("couldn't write to {}: {}", display, why),
        Ok(_) => println!("successfully wrote to {}", display),
    }
    drop(file);
    let file=File::open(&path).unwrap();
    let mmap = unsafe { memmap2::Mmap::map(&file).unwrap() };
    drop(file);
    assert!(path.try_exists().unwrap());
    fs::remove_file(path).unwrap();
    assert_eq!(CONTENT.as_bytes(), &mmap[0..19]);
    assert!(path.try_exists().unwrap());
}

The test fails on the last line because the path does not exists.
Is this the expected behavior?
I was expecting a failure at fs::remove_file(path).unwrap(); because windows locks the file if it's mmapped.
I tried to search for some documentation but I was unable to find anything useful.
Can anyone tell me what I'm missing and provide some references in order to better understand what "is happening under the covers"?

AFAIK that's not the behaviour. You need to lock the file when you open it, which the stdlib's File::open doesn't do.

If you map it as executable it should not allow deleting the underlying file but other than that I don't think mapping will implicitly add locks.

thanks, do you have some reference to a documentation about the locking behaviour? It would help me to better understand how I can manage the file mapping

thanks, I tried adding the SEC_IMAGE flag, but the result is still the same, so I guess it's somethinng related to opening the file with some share attributes.

I believe you're looking for OpenOptions::share_mode. If you check out the CreateFileW and scroll down to dwShareMode it'll explain what the options mean.

A cross platform solution is fd-lock that can lock and unlock an open file. Note that on unix-like systems locks tend to be "advisory" (i.e. it's possible for people to bypass them if they want to),

Something like this should "work" (by which I mean error when you try to delete), but the previous solution is better if you don't need the memory to be executable.

let mmap = unsafe { MmapOptions::new().map_exec(&file).unwrap() };

EDIT: Ah no, that won't work because MmapOptions doesn't use SEC_IMAGE.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.