From 9c964695ae513652cb87239dab6a17420ac97806 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Wed, 10 Feb 2016 19:55:38 -0600 Subject: [PATCH] win32_capture.c: retry NtReadFile() requests --- src/win32_capture.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/win32_capture.c b/src/win32_capture.c index 0d4b783e..c9e8ba1b 100644 --- a/src/win32_capture.c +++ b/src/win32_capture.c @@ -360,9 +360,12 @@ read_winnt_stream_prefix(const struct windows_file *file, IO_STATUS_BLOCK iosb; ULONG count; ULONG bytes_read; + const unsigned max_tries = 5; + unsigned tries_remaining = max_tries; count = min(sizeof(buf), bytes_remaining); + retry_read: status = (*func_NtReadFile)(h, NULL, NULL, NULL, &iosb, buf, count, NULL, NULL); if (unlikely(!NT_SUCCESS(status))) { @@ -371,11 +374,28 @@ read_winnt_stream_prefix(const struct windows_file *file, windows_file_to_string(file, buf, sizeof(buf))); ret = WIMLIB_ERR_CONCURRENT_MODIFICATION_DETECTED; } else { - winnt_error(status, L"Error reading data from %ls", - windows_file_to_string(file, buf, sizeof(buf))); + winnt_warning(status, L"Error reading data from %ls", + windows_file_to_string(file, buf, sizeof(buf))); + + /* Currently these retries are purely a guess; + * there is no reproducible problem that they solve. */ + if (--tries_remaining) { + int delay = 100; + if (status == STATUS_INSUFFICIENT_RESOURCES || + status == STATUS_NO_MEMORY) { + delay *= 25; + } + WARNING("Retrying after %dms...", delay); + Sleep(delay); + goto retry_read; + } + ERROR("Too many retries; returning failure"); ret = WIMLIB_ERR_READ; } break; + } else if (unlikely(tries_remaining != max_tries)) { + WARNING("A read request had to be retried multiple times " + "before it succeeded!"); } bytes_read = iosb.Information; -- 2.43.0