This is an archive of the discontinued LLVM Phabricator instance.

Use a single file name to represent a lock
AbandonedPublic

Authored by rafael on Nov 21 2017, 6:08 PM.

Details

Summary

Currently the lock logic is

  • Create a temp file
  • Create a symbolic link on unix or a hard link on windows
  • Delete both when we are done with it

The problem is that CreateHardLink on windows will fail if the file has a DeleteFile disposition which I want to use in TempFile.

The solution I think is to use a single file for the lock. On windows that is simple as rename can be set to fail if the destination exists.

On posix we first create the link as we do now, but immediately rename the original file onto it.

Diff Detail

Event Timeline

rafael created this revision.Nov 21 2017, 6:08 PM

Out of curiosity, what do we use LockFileManager for in LLVM, and what are you trying to use it for in this specific use case? Because of certain quirks in Windows file system semantics, lock files are in general not a robust solution most of the time -- maybe even ever.

If all use cases of lock files are to synchronize cross-process, why don't we just re-write LockFileManager to use a named mutex?

amccarth edited edge metadata.Nov 22 2017, 8:16 AM

I share zturner's concerns that file-based lock implementations on Windows are inherently fraught with pitfalls. Can't we use a Mutex or other OS-provided synchronization mechanism? Those will be more efficient, more robust, and they won't leave artifacts if the program is interrupted or crashes.

include/llvm/Support/FileSystem.h
386

I'm not a fan of this interface, with both From and FD. It's confusing and seems prone to being called erroneously. What if the caller accidentally specifies a From that doesn't correspond to FD?

And it appears that neither implementation currently uses FD. I see the FIXME that suggests it might be useful in the future. Can we remove FD for now and revisit it later?

763

I had to read the second sentence a couple times to understand it, and, once I did, it still left me with questions. For example, if there is an existing file with Name, does the function return an error? May I suggest:

// Change the name of the temporary file.  If a file with Name already exists,
// this does nothing and returns an Error.  This will still be a temporary
// file, so keep or discard should still be called.
lib/Support/Unix/Path.inc
433

s/istead/instead/

lib/Support/Windows/Path.inc
1044

s/.begin()/.data()/

Don't use DELETE access unconditionally. It can block non llvm code from accessing the file if they don't use SHARE_DELETE.

Address review comments.

I found a way to use FILE_FLAG_DELETE_ON_CLOSE without this.

I think think that using a single file for the lock is an improvement, but it is now independent.

rnk edited edge metadata.Nov 27 2017, 1:33 PM

I just assume that LockFileManager doesn't actually work on Windows. It's really only used by implicit modules, and we're pushing people away from those anyway. If we don't need this for the TempFile migration, I say let sleeping broken code lie, unless you think this simplification is worth it for Posix systems.

rafael abandoned this revision.Nov 27 2017, 1:56 PM