Esempio n. 1
0
        public AbsoluteDirectoryPath Acquire(AbsoluteDirectoryPath baseDirectory)
        {
            var buildLock = new Optional <BuildOutputDirLock>();

            _fileSystem.MakeUnique(baseDirectory,
                                   createName: no => baseDirectory.Rename(MakePathUnique.CreateNumberName(baseDirectory.Name, no)),
                                   condition: p =>
            {
                buildLock = new BuildOutputDirLock(
                    p,
                    () =>
                {
                    BuildOutputDirLock tmp;
                    var tries = 5;
                    while (!_lockedBuildDirectories.TryRemove(p, out tmp) && tries >= 0)
                    {
                        --tries;
                    }
                });
                var result = _lockedBuildDirectories.AddOrUpdate(
                    p,
                    buildLock.Value,
                    (buildOut, oldLock) => oldLock);

                // If we did update an already lock - try to iterate over other possibilities.
                return(result != buildLock);
            });

            buildLock.Do(bl => bl.Lock());
            return(buildLock
                   .OrThrow(new Exception("Failed to generate a build output directory."))
                   .BuildDir);
        }
Esempio n. 2
0
        /// <exception cref="FailedToCreateOutputDir"></exception>
        public OutputDirWithLock CreateOrReuseOutputDir(AbsoluteDirectoryPath baseDir)
        {
            try
            {
                const int fileInUse  = 0x20;
                const int fileLocked = 0x21;

                LockFile lockFile = null;
                var      path     = _fileSystem.MakeUnique(baseDir,
                                                           createName: no => baseDir.Rename(MakePathUnique.CreateNumberName(baseDir.Name, no)),
                                                           condition: p =>
                {
                    try
                    {
                        if (!_fileSystem.Exists(p))
                        {
                            _fileSystem.Create(p);
                        }

                        var lockFilePath = p / new FileName(".lock");
                        lockFile         = new LockFile(lockFilePath);
                        return(false);                                // If the file wasn't locked, break creating of unique directories.
                    }
                    catch (IOException e)
                    {
                        var win32ErrorCode = e.HResult & 0xFFFF;
                        if (win32ErrorCode == fileLocked || win32ErrorCode == fileInUse)
                        {
                            return(true);                                    // If the file was locked, continue creating unique directories.
                        }
                        throw;
                    }
                });

                return(new OutputDirWithLock(path, lockFile));
            }
            catch (Exception e)
            {
                throw new FailedToCreateOutputDir(baseDir, e);
            }
        }