-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Avoiding loading and processing same cert file to improve cold start performance … #97267
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -114,7 +114,7 @@ private static bool LastWriteTimesHaveChanged() | |
|
||
if (s_rootStoreFile != null) | ||
{ | ||
_ = TryStatFile(s_rootStoreFile, out DateTime lastModified); | ||
_ = TryStatFile(s_rootStoreFile, out DateTime lastModified, out _); | ||
if (lastModified != s_fileLastWrite) | ||
{ | ||
return true; | ||
|
@@ -149,6 +149,7 @@ private static Tuple<SafeX509StackHandle, SafeX509StackHandle> LoadMachineStores | |
|
||
var uniqueRootCerts = new HashSet<X509Certificate2>(); | ||
var uniqueIntermediateCerts = new HashSet<X509Certificate2>(); | ||
var processedFiles = new HashSet<(long Ino, long Dev)>(); | ||
bool firstLoad = (s_nativeCollections == null); | ||
|
||
if (firstLoad) | ||
|
@@ -197,23 +198,23 @@ bool ProcessDir(string dir, out DateTime lastModified) | |
|
||
foreach (string file in Directory.EnumerateFiles(dir)) | ||
{ | ||
hasStoreData |= ProcessFile(file, out _, skipStat: true); | ||
hasStoreData |= ProcessFile(file, out _); | ||
} | ||
|
||
return hasStoreData; | ||
} | ||
|
||
bool ProcessFile(string file, out DateTime lastModified, bool skipStat = false) | ||
bool ProcessFile(string file, out DateTime lastModified) | ||
{ | ||
bool readData = false; | ||
|
||
if (skipStat) | ||
if (!TryStatFile(file, out lastModified, out (long, long) fileId)) | ||
{ | ||
lastModified = default; | ||
return false; | ||
} | ||
else if (!TryStatFile(file, out lastModified)) | ||
|
||
if (processedFiles.Contains(fileId)) | ||
{ | ||
return false; | ||
return true; | ||
} | ||
|
||
using (SafeBioHandle fileBio = Interop.Crypto.BioNewFile(file, "rb")) | ||
|
@@ -281,6 +282,11 @@ bool ProcessFile(string file, out DateTime lastModified, bool skipStat = false) | |
} | ||
} | ||
|
||
if (readData) | ||
{ | ||
processedFiles.Add(fileId); | ||
} | ||
|
||
return readData; | ||
} | ||
|
||
|
@@ -307,7 +313,6 @@ bool ProcessFile(string file, out DateTime lastModified, bool skipStat = false) | |
// In order to maintain "finalization-free" the GetNativeCollections method would need to | ||
// DangerousAddRef, and the callers would need to DangerousRelease, adding more interlocked operations | ||
// on every call. | ||
|
||
Volatile.Write(ref s_nativeCollections, newCollections); | ||
s_recheckStopwatch.Restart(); | ||
return newCollections; | ||
|
@@ -361,24 +366,24 @@ private static string[] GetRootStoreDirectories(out bool isDefault) | |
return directories; | ||
} | ||
|
||
private static bool TryStatFile(string path, out DateTime lastModified) | ||
=> TryStat(path, Interop.Sys.FileTypes.S_IFREG, out lastModified); | ||
|
||
private static bool TryStatDirectory(string path, out DateTime lastModified) | ||
=> TryStat(path, Interop.Sys.FileTypes.S_IFDIR, out lastModified); | ||
=> TryStat(path, Interop.Sys.FileTypes.S_IFDIR, out lastModified, out _); | ||
|
||
private static bool TryStat(string path, int fileType, out DateTime lastModified) | ||
private static bool TryStatFile(string path, out DateTime lastModified, out (long, long) fileId) | ||
|
||
=> TryStat(path, Interop.Sys.FileTypes.S_IFREG, out lastModified, out fileId); | ||
|
||
private static bool TryStat(string path, int fileType, out DateTime lastModified, out (long, long) fileId) | ||
{ | ||
Comment on lines
368
to
376
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ideally the TryStatFile/TryStatDirectory order would have been maintained so the diff showed that it was really just adding the out. But, again, it's not worth spinning on. |
||
lastModified = default; | ||
|
||
Interop.Sys.FileStatus status; | ||
fileId = default; | ||
// Use Stat to follow links. | ||
if (Interop.Sys.Stat(path, out status) < 0 || | ||
if (Interop.Sys.Stat(path, out Interop.Sys.FileStatus status) < 0 || | ||
(status.Mode & Interop.Sys.FileTypes.S_IFMT) != fileType) | ||
{ | ||
return false; | ||
} | ||
|
||
fileId = (status.Ino, status.Dev); | ||
lastModified = DateTime.UnixEpoch + TimeSpan.FromTicks(status.MTime * TimeSpan.TicksPerSecond + status.MTimeNsec / TimeSpan.NanosecondsPerTick); | ||
return true; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The blank line shouldn't have been removed, since the comment isn't about the following code, it's about code that's not present; making it a separate logical code paragraph. But it's not worth spinning on.