From b261dd4d3a15d17f4f559d4669eb1784df8012ab Mon Sep 17 00:00:00 2001 From: mptyl Date: Tue, 18 Aug 2026 14:49:56 +0200 Subject: [PATCH] fix(windows): serialize private root contention --- .../internal/safeio/private_root_windows.go | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/tools/tht/internal/safeio/private_root_windows.go b/tools/tht/internal/safeio/private_root_windows.go index e57b9735..16885053 100644 --- a/tools/tht/internal/safeio/private_root_windows.go +++ b/tools/tht/internal/safeio/private_root_windows.go @@ -82,7 +82,7 @@ func openWindowsPrivateDirectoryAt(parent windows.Handle, name string, ensure bo return 0, false, ErrUnsafeFile } for attempt := 0; attempt < 2; attempt++ { - handle, err := openWindowsRelativeDirectory(parent, name) + handle, err := openWindowsRelativePrivateDirectoryWithRetry(parent, name) if err == nil { return handle, true, nil } @@ -100,6 +100,19 @@ func openWindowsPrivateDirectoryAt(parent windows.Handle, name string, ensure bo return 0, false, ErrUnsafeFile } +func openWindowsRelativePrivateDirectoryWithRetry(parent windows.Handle, name string) (windows.Handle, error) { + for attempt := 0; ; attempt++ { + handle, err := openWindowsRelativeDirectory(parent, name) + if !isWindowsRelativeSharingViolation(err) { + return handle, err + } + if attempt == windowsPrivateSharingRetries { + return 0, err + } + time.Sleep(time.Millisecond) + } +} + func openWindowsRelativeDirectory(parent windows.Handle, name string) (windows.Handle, error) { handle, err := openWindowsRelativeObject( parent, @@ -280,6 +293,11 @@ func isWindowsRelativeCollision(err error) bool { errors.Is(err, windows.STATUS_OBJECT_NAME_COLLISION) } +func isWindowsRelativeSharingViolation(err error) bool { + return errors.Is(err, windows.ERROR_SHARING_VIOLATION) || + errors.Is(err, windows.STATUS_SHARING_VIOLATION) +} + func (directory *windowsPrivateDirectory) captureAndValidate() error { if directory == nil || directory.handle == 0 { return ErrUnsafeFile @@ -953,7 +971,7 @@ func windowsRelativeClaimAbsentOrOrphan(directory *windowsPrivateDirectory, sour return false, ErrUnsafeFile } -const windowsClaimSharingRetries = 100 +const windowsPrivateSharingRetries = 100 func waitForWindowsRelativeClaimLoss(directory *windowsPrivateDirectory, source, claim string) (bool, error) { for attempt := 0; ; attempt++ { @@ -965,7 +983,7 @@ func waitForWindowsRelativeClaimLoss(directory *windowsPrivateDirectory, source, if absentErr == nil && absent { return true, nil } - if attempt == windowsClaimSharingRetries { + if attempt == windowsPrivateSharingRetries { return false, ErrUnsafeFile } time.Sleep(time.Millisecond) @@ -980,11 +998,10 @@ func openWindowsPrivateClaimRegular( ) (*windowsPrivateRegularAt, error) { for attempt := 0; ; attempt++ { value, err := openWindowsPrivateRegularAt(directory, name, access, allowedLinks) - if !errors.Is(err, windows.ERROR_SHARING_VIOLATION) && - !errors.Is(err, windows.STATUS_SHARING_VIOLATION) { + if !isWindowsRelativeSharingViolation(err) { return value, err } - if attempt == windowsClaimSharingRetries { + if attempt == windowsPrivateSharingRetries { return nil, err } time.Sleep(time.Millisecond)