about summary refs log tree commit diff
path: root/compiler/rustc_incremental/src
diff options
context:
space:
mode:
authorCamille GILLOT <gillot.camille@gmail.com>2021-03-17 22:49:16 +0100
committerCamille GILLOT <gillot.camille@gmail.com>2021-08-28 21:45:02 +0200
commit98007e2ce6f3731a935b0541d6ef63f292ef7ab9 (patch)
tree3e1e5461a5a7e21cae171e1a3efa6d4f40e5461d /compiler/rustc_incremental/src
parent6b47e1ece87f8cb96709b772dbea1a2a979c1cbd (diff)
downloadrust-98007e2ce6f3731a935b0541d6ef63f292ef7ab9.tar.gz
rust-98007e2ce6f3731a935b0541d6ef63f292ef7ab9.zip
Drop the query result memmap before serializing it back.
Diffstat (limited to 'compiler/rustc_incremental/src')
-rw-r--r--compiler/rustc_incremental/src/persist/file_format.rs11
-rw-r--r--compiler/rustc_incremental/src/persist/save.rs5
2 files changed, 15 insertions, 1 deletions
diff --git a/compiler/rustc_incremental/src/persist/file_format.rs b/compiler/rustc_incremental/src/persist/file_format.rs
index 2da72bfc292..572a4fc6971 100644
--- a/compiler/rustc_incremental/src/persist/file_format.rs
+++ b/compiler/rustc_incremental/src/persist/file_format.rs
@@ -52,7 +52,10 @@ where
     // Delete the old file, if any.
     // Note: It's important that we actually delete the old file and not just
     // truncate and overwrite it, since it might be a shared hard-link, the
-    // underlying data of which we don't want to modify
+    // underlying data of which we don't want to modify.
+    //
+    // We have to ensure we have dropped the memory maps to this file
+    // before performing this removal.
     match fs::remove_file(&path_buf) {
         Ok(()) => {
             debug!("save: remove old file");
@@ -114,6 +117,12 @@ pub fn read_file(
         Err(err) if err.kind() == io::ErrorKind::NotFound => return Ok(None),
         Err(err) => return Err(err),
     };
+    // SAFETY: This process must not modify nor remove the backing file while the memory map lives.
+    // For the dep-graph and the work product index, it is as soon as the decoding is done.
+    // For the query result cache, the memory map is dropped in save_dep_graph before calling
+    // save_in and trying to remove the backing file.
+    //
+    // There is no way to prevent another process from modifying this file.
     let mmap = unsafe { Mmap::map(file) }?;
 
     let mut file = io::Cursor::new(&*mmap);
diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs
index 2feba71e010..6c683058b12 100644
--- a/compiler/rustc_incremental/src/persist/save.rs
+++ b/compiler/rustc_incremental/src/persist/save.rs
@@ -42,6 +42,11 @@ pub fn save_dep_graph(tcx: TyCtxt<'_>) {
         join(
             move || {
                 sess.time("incr_comp_persist_result_cache", || {
+                    // Drop the memory map so that we can remove the file and write to it.
+                    if let Some(odc) = &tcx.on_disk_cache {
+                        odc.drop_serialized_data(tcx);
+                    }
+
                     file_format::save_in(sess, query_cache_path, "query cache", |e| {
                         encode_query_cache(tcx, e)
                     });