<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, Nov 6, 2017 at 11:25 AM, Rafael Avila de Espindola <span dir="ltr"><<a href="mailto:rafael.espindola@gmail.com" target="_blank">rafael.espindola@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">Rui Ueyama via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> writes:<br>
<br>
> +// A FileOutputBuffer which creates a temporary file in the same directory<br>
> +// as the final output file. The final output file is atomically replaced<br>
> +// with the temporary file on commit().<br>
> +class OnDiskBuffer : public FileOutputBuffer {<br>
> +public:<br>
> +  OnDiskBuffer(StringRef Path, StringRef TempPath,<br>
> +               std::unique_ptr<fs::mapped_<wbr>file_region> Buf)<br>
> +      : FileOutputBuffer(Path), Buffer(std::move(Buf)), TempPath(TempPath) {}<br>
</span><span class="">> +  static ErrorOr<std::unique_ptr<<wbr>OnDiskBuffer>><br>
> +  create(StringRef Path, size_t Size, unsigned Mode);<br>
<br>
</span>Why do you need both a public constructor and a create method? Can the<br>
constructor be private?</blockquote><div><br></div><div>I couldn't use llvm::make_unique without making the constructor public.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">
> +// A FileOutputBuffer which keeps data in memory and writes to the final<br>
> +// output file on commit(). This is used only when we cannot use OnDiskBuffer.<br>
> +class InMemoryBuffer : public FileOutputBuffer {<br>
> +public:<br>
> +  InMemoryBuffer(StringRef Path, MemoryBlock Buf, unsigned Mode)<br>
> +      : FileOutputBuffer(Path), Buffer(Buf), Mode(Mode) {}<br>
> +<br>
> +  static ErrorOr<std::unique_ptr<<wbr>InMemoryBuffer>><br>
> +  create(StringRef Path, size_t Size, unsigned Mode) {<br>
<br>
</span>Same here. Why both a public constructor and create?<br>
<span class=""><br>
> +  std::error_code commit() override {<br>
> +    int FD;<br>
> +    std::error_code EC;<br>
> +    if (auto EC = openFileForWrite(FinalPath, FD, fs::F_None, Mode))<br>
> +      return EC;<br>
> +    raw_fd_ostream OS(FD, /*shouldClose=*/true, /*unbuffered=*/true);<br>
> +    OS << StringRef((const char *)Buffer.base(), Buffer.size());<br>
> +    return std::error_code();<br>
<br>
</span>This is currently correct as this method is never used with regular<br>
files.<br>
<br>
Is the idea to use InMemoryBuffer for where we don't have a way of<br>
allocating an output file? If so when we do that this should still use a<br>
temporary file if the output is a regular file.<br></blockquote><div><br></div><div>Can you elaborate?</div><div><br></div><div>Currently, if you cannot create a temporary file in the same directory as the output file, FileOutputBuffer creates an in-memory buffer instead of creating a temporary file in a temporary directory (e.g. /tmp), as there's no guarantee that the temporary directory and the destination directory are on the same filesystem.</div></div></div></div>