fix(windows): serialize private root contention
This commit is contained in:
@@ -82,7 +82,7 @@ func openWindowsPrivateDirectoryAt(parent windows.Handle, name string, ensure bo
|
|||||||
return 0, false, ErrUnsafeFile
|
return 0, false, ErrUnsafeFile
|
||||||
}
|
}
|
||||||
for attempt := 0; attempt < 2; attempt++ {
|
for attempt := 0; attempt < 2; attempt++ {
|
||||||
handle, err := openWindowsRelativeDirectory(parent, name)
|
handle, err := openWindowsRelativePrivateDirectoryWithRetry(parent, name)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return handle, true, nil
|
return handle, true, nil
|
||||||
}
|
}
|
||||||
@@ -100,6 +100,19 @@ func openWindowsPrivateDirectoryAt(parent windows.Handle, name string, ensure bo
|
|||||||
return 0, false, ErrUnsafeFile
|
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) {
|
func openWindowsRelativeDirectory(parent windows.Handle, name string) (windows.Handle, error) {
|
||||||
handle, err := openWindowsRelativeObject(
|
handle, err := openWindowsRelativeObject(
|
||||||
parent,
|
parent,
|
||||||
@@ -280,6 +293,11 @@ func isWindowsRelativeCollision(err error) bool {
|
|||||||
errors.Is(err, windows.STATUS_OBJECT_NAME_COLLISION)
|
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 {
|
func (directory *windowsPrivateDirectory) captureAndValidate() error {
|
||||||
if directory == nil || directory.handle == 0 {
|
if directory == nil || directory.handle == 0 {
|
||||||
return ErrUnsafeFile
|
return ErrUnsafeFile
|
||||||
@@ -953,7 +971,7 @@ func windowsRelativeClaimAbsentOrOrphan(directory *windowsPrivateDirectory, sour
|
|||||||
return false, ErrUnsafeFile
|
return false, ErrUnsafeFile
|
||||||
}
|
}
|
||||||
|
|
||||||
const windowsClaimSharingRetries = 100
|
const windowsPrivateSharingRetries = 100
|
||||||
|
|
||||||
func waitForWindowsRelativeClaimLoss(directory *windowsPrivateDirectory, source, claim string) (bool, error) {
|
func waitForWindowsRelativeClaimLoss(directory *windowsPrivateDirectory, source, claim string) (bool, error) {
|
||||||
for attempt := 0; ; attempt++ {
|
for attempt := 0; ; attempt++ {
|
||||||
@@ -965,7 +983,7 @@ func waitForWindowsRelativeClaimLoss(directory *windowsPrivateDirectory, source,
|
|||||||
if absentErr == nil && absent {
|
if absentErr == nil && absent {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
if attempt == windowsClaimSharingRetries {
|
if attempt == windowsPrivateSharingRetries {
|
||||||
return false, ErrUnsafeFile
|
return false, ErrUnsafeFile
|
||||||
}
|
}
|
||||||
time.Sleep(time.Millisecond)
|
time.Sleep(time.Millisecond)
|
||||||
@@ -980,11 +998,10 @@ func openWindowsPrivateClaimRegular(
|
|||||||
) (*windowsPrivateRegularAt, error) {
|
) (*windowsPrivateRegularAt, error) {
|
||||||
for attempt := 0; ; attempt++ {
|
for attempt := 0; ; attempt++ {
|
||||||
value, err := openWindowsPrivateRegularAt(directory, name, access, allowedLinks)
|
value, err := openWindowsPrivateRegularAt(directory, name, access, allowedLinks)
|
||||||
if !errors.Is(err, windows.ERROR_SHARING_VIOLATION) &&
|
if !isWindowsRelativeSharingViolation(err) {
|
||||||
!errors.Is(err, windows.STATUS_SHARING_VIOLATION) {
|
|
||||||
return value, err
|
return value, err
|
||||||
}
|
}
|
||||||
if attempt == windowsClaimSharingRetries {
|
if attempt == windowsPrivateSharingRetries {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
time.Sleep(time.Millisecond)
|
time.Sleep(time.Millisecond)
|
||||||
|
|||||||
Reference in New Issue
Block a user