Skip to content
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

HostModel: Retry ResourceUpdate on Win32 error #32347

Merged
merged 1 commit into from
Feb 19, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 34 additions & 7 deletions src/installer/managed/Microsoft.NET.HostModel/AppHost/RetryUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,43 @@ public static void RetryOnIOError(Action func)

public static void RetryOnWin32Error(Action func)
{
bool IsWin32FileLockError(int hresult)
bool IsKnownIrrecoverableError(int hresult)
{
// Error codes are defined in winerror.h
const int ErrorLockViolation = 33;
const int ErrorDriveLocked = 108;

// The error code is stored in the lowest 16 bits of the HResult
int errorCode = hresult & 0xffff;

return errorCode == ErrorLockViolation || errorCode == ErrorDriveLocked;
switch (hresult & 0xffff)
{
case 0x00000001: // ERROR_INVALID_FUNCTION
case 0x00000002: // ERROR_FILE_NOT_FOUND
case 0x00000003: // ERROR_PATH_NOT_FOUND
case 0x00000006: // ERROR_INVALID_HANDLE
case 0x00000008: // ERROR_NOT_ENOUGH_MEMORY
case 0x0000000B: // ERROR_BAD_FORMAT
case 0x0000000E: // ERROR_OUTOFMEMORY
case 0x0000000F: // ERROR_INVALID_DRIVE
case 0x00000012: // ERROR_NO_MORE_FILES
case 0x00000035: // ERROR_BAD_NETPATH
case 0x00000057: // ERROR_INVALID_PARAMETER
case 0x00000071: // ERROR_NO_MORE_SEARCH_HANDLES
case 0x00000072: // ERROR_INVALID_TARGET_HANDLE
case 0x00000078: // ERROR_CALL_NOT_IMPLEMENTED
case 0x0000007B: // ERROR_INVALID_NAME
case 0x0000007C: // ERROR_INVALID_LEVEL
case 0x0000007D: // ERROR_NO_VOLUME_LABEL
case 0x0000009A: // ERROR_LABEL_TOO_LONG
case 0x000000A0: // ERROR_BAD_ARGUMENTS
case 0x000000A1: // ERROR_BAD_PATHNAME
case 0x000000CE: // ERROR_FILENAME_EXCED_RANGE
case 0x000000DF: // ERROR_FILE_TOO_LARGE
case 0x000003ED: // ERROR_UNRECOGNIZED_VOLUME
case 0x000003EE: // ERROR_FILE_INVALID
case 0x00000651: // ERROR_DEVICE_REMOVED
Comment on lines +51 to +75
Copy link

@brcaswell brcaswell Mar 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you provide some insight on how you came up with this list of codes, and whether or not you anticipate more codes to be added upon further review?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wrote down a list of error code by inspecting the windows error codes, scanning for errors that cannot succeed on retry. The list is conservative; that is, there could be more failures that shouldn't be retried. But I do not anticipate adding more codes to this list. I believe tripping into one of these cases is rare, since the file to be accessed is created by the HostModel library itself.

return true;

default:
return false;
}
}

for (int i = 1; i <= NumberOfRetries; i++)
Expand All @@ -61,7 +88,7 @@ bool IsWin32FileLockError(int hresult)
break;
}
catch (HResultException hrex)
when (i < NumberOfRetries && IsWin32FileLockError(hrex.Win32HResult))
when (i < NumberOfRetries && !IsKnownIrrecoverableError(hrex.Win32HResult))
{
Thread.Sleep(NumMilliSecondsToWait);
}
Expand Down