diff --git a/src/Microsoft.ML.Data/Model/Repository.cs b/src/Microsoft.ML.Data/Model/Repository.cs index 7556cc970e..b19fbc8eba 100644 --- a/src/Microsoft.ML.Data/Model/Repository.cs +++ b/src/Microsoft.ML.Data/Model/Repository.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using System.IO; using System.IO.Compression; -using Microsoft.ML.Runtime.Data; using Microsoft.ML.Runtime.Internal.Utilities; namespace Microsoft.ML.Runtime.Model @@ -73,7 +72,7 @@ public void Dispose() } } - // These are the open entries that may contain streams into our _dirTemp. + // These are the open entries that may contain streams into our DirTemp. private List<Entry> _open; private bool _disposed; @@ -108,19 +107,37 @@ internal Repository(bool needDir, IExceptionContext ectx) PathMap = new Dictionary<string, string>(); _open = new List<Entry>(); if (needDir) - { - DirTemp = GetTempPath(); - Directory.CreateDirectory(DirTemp); - } + DirTemp = GetShortTempDir(); else GC.SuppressFinalize(this); } - // REVIEW: This should use host environment functionality. - private static string GetTempPath() + private static string GetShortTempDir() + { + var rnd = RandomUtils.Create(); + string path; + do + { + path = Path.Combine(Path.GetTempPath(), "TLC_" + rnd.Next().ToString("X")); + path = Path.GetFullPath(path); + Directory.CreateDirectory(path); + } + while (!EnsureDirectory(path)); + return path; + } + + private static bool EnsureDirectory(string path) { - Guid guid = Guid.NewGuid(); - return Path.GetFullPath(Path.Combine(Path.GetTempPath(), "TLC_" + guid.ToString())); + path = Path.GetFullPath(Path.Combine(path, ".lock")); + try + { + using (var stream = new FileStream(path, FileMode.CreateNew)) + return true; + } + catch + { + return false; + } } ~Repository() @@ -232,7 +249,7 @@ protected void GetPath(out string pathEnt, out string pathTemp, string dir, stri _ectx.CheckParam(!name.Contains(".."), nameof(name)); // The gymnastics below are meant to deal with bad invocations including absolute paths, etc. - // That's why we go through it even if _dirTemp is null. + // That's why we go through it even if DirTemp is null. string root = Path.GetFullPath(DirTemp ?? @"x:\dummy"); string entityPath = Path.Combine(root, dir ?? "", name); entityPath = Path.GetFullPath(entityPath);