This is an archive of the discontinued LLVM Phabricator instance.

Use FILE_FLAG_DELETE_ON_CLOSE for TempFile on windows
ClosedPublic

Authored by rafael on Nov 23 2017, 1:57 PM.

Details

Reviewers
rnk
Summary

With this llvm should never leave a temporary file behind.

Diff Detail

Event Timeline

rafael created this revision.Nov 23 2017, 1:57 PM
rafael added a parent revision: D40400: Move code.

Rebase now that it doesn't depend on the LockFileManager change.

rafael edited parent revisions, added: D40446: move code; removed: D40400: Move code.Nov 24 2017, 9:58 AM
rnk added inline comments.Nov 27 2017, 10:31 AM
lib/Support/Windows/Path.inc
403–405

The atomicity concern didn't bother me that much. There are two windows where the temp file may remain: when the process dies between CreateFileW and the SetFileInformationByHandle Delete=true call, and when the process dies between SetFileInformationByHandle Delete=false and the file rename. It's highly unlikely that we will crash in either of these places. There would have to be an external source of raciness (a second thread or external process killing the process) to cause this bug. It doesn't seem like a show-stopper. The FILE_FLAG_DELETE_ON_CLOSE solution doesn't close the second window.

Can you elaborate on the usability problem, since it's more important? If we tolerate the raciness above, not being able to rename a temporary file isn't such a big deal as long as the TempFile abstraction turns off the delete-on-close disposition before renaming. Do we have uses of TempFile that want to be able to pass the path to some other open() call?

I think it simplifies the code to use separate calls to set the file disposition, if that's possible. Then we don't need to change the user FD and handle all as many error edge cases.

407–411

Is this something you figured out through experimentation or is there some reference, documentation, stack overflow post, etc that explains this technique? It's an awfully convoluted way to get the obviously desirable behavior. :)

423–424

I think we should call ::close(FD) here instead to avoid leaking the FD table entry in the CRT. Stack Overflow suggests that there is no way to close an FD without calling CloseHandle on the underlying handle. I suspect you can still use GetLastError, but I can't find any docs to confirm that.

Use close. Expand comment.

rnk accepted this revision.Nov 27 2017, 4:53 PM

Cool, looks good. :)

This revision is now accepted and ready to land.Nov 27 2017, 4:53 PM