But the Source file is just a temporary file right that’s not (yet) part of the cache right?  So why would another process be accessing the same temporary file instead of creating a different one?<br><br><br>If the problem is with Dest, I could understand, but it opens that one with sharing so it can’t be that.<br><br>Is the Source file already part of the cache for some reason?<br><br>Btw, I have an (absolutely terrible) idea how to solve this “for real”, but I’ll save it until I understand the problem better <br><div class="gmail_quote"><div dir="ltr">On Wed, Oct 4, 2017 at 6:38 PM Peter Collingbourne via Phabricator <<a href="mailto:reviews@reviews.llvm.org">reviews@reviews.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">pcc added a comment.<br>
<br>
In <a href="https://reviews.llvm.org/D38570#889021" rel="noreferrer" target="_blank">https://reviews.llvm.org/D38570#889021</a>, @zturner wrote:<br>
<br>
> So if I understand the problem correctly, you don't have any issue with `ReplaceFile`'s behavior on the destination, only the source.  So, for example, you call `ReplaceFile`, it returns, and then some other process tries to open the //source// file and fails.<br>
<br>
<br>
Not quite. From the ThinLTO perspective I don't care about the behaviour on the source file before it is renamed, because all source files are temporary files whose names are unknown to other processes. The problem is with the behaviour on the source file after it has been renamed to the destination file. ThinLTO does this for each new cache file that it creates:<br>
<br>
  rename("thinlto-cache/temporary file name", "thinlto-cache/llvmcache-ABC123") // ABC123 is a unique hash that is computed from the linker's input files and command line options. There is a many-to-one mapping from hashes to object files (modulo collisions, but that's unlikely enough not to matter).<br>
<br>
In parallel, another process will be doing this in order to try and open an existing cache file:<br>
<br>
  open("thinlto-cache/llvmcache-ABC123") // This is expected to either succeed (cache hit) or return "no such file or directory" (cache miss).<br>
<br>
Where this breaks is when `rename` is implemented in terms of `ReplaceFile`. In pseudocode, here's what I think is going on in the important part of `ReplaceFile`:<br>
<br>
  void ReplaceFile(char *Src, char *Dst) {<br>
    HANDLE h = CreateFile(Src, no sharing); // (1) Src cannot be opened<br>
    SetFileInformationByHandle(h, Rename, Dst); // (2) Now Dst cannot be opened<br>
    CloseFile(h); // (3) Now Dst can be opened<br>
  }<br>
<br>
So if the `open` happens between 2 and 3, it will get a permission denied error, which is not what the caller of `open` is expecting.<br>
<br>
<br>
<a href="https://reviews.llvm.org/D38570" rel="noreferrer" target="_blank">https://reviews.llvm.org/D38570</a><br>
<br>
<br>
<br>
</blockquote></div>