Remove exponential backoff from chdir()

This issue probably only impacted the earliest releases of Windows 7 and
we only support Windows 10+ these days, so it's not worth adding 2000 ms
of startup latency to vim when ~/.vim doesn't exist.
This commit is contained in:
Justine Tunney 2024-09-10 21:21:52 -07:00
parent 4d05060aac
commit deb5e07b5a
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
2 changed files with 23 additions and 46 deletions

View file

@ -16,34 +16,23 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/calls/syscall-nt.internal.h"
#include "libc/calls/syscall_support-nt.internal.h" #include "libc/calls/syscall_support-nt.internal.h"
#include "libc/errno.h" #include "libc/limits.h"
#include "libc/macros.h"
#include "libc/nt/errors.h"
#include "libc/nt/files.h" #include "libc/nt/files.h"
#include "libc/nt/process.h" #include "libc/nt/process.h"
#include "libc/nt/runtime.h"
#include "libc/nt/synchronization.h"
#include "libc/sysv/errfuns.h" #include "libc/sysv/errfuns.h"
textwindows int sys_chdir_nt_impl(char16_t path[hasatleast PATH_MAX], textwindows int sys_chdir_nt_impl(char16_t path[hasatleast PATH_MAX],
uint32_t len) { uint32_t len) {
uint32_t n; uint32_t n;
int e, ms, err;
char16_t var[4]; char16_t var[4];
if (len && path[len - 1] != u'\\') { if (len && path[len - 1] != u'\\') {
if (len + 2 > PATH_MAX) if (len + 2 > PATH_MAX)
return enametoolong(); return enametoolong();
path[len + 0] = u'\\'; path[len + 0] = u'\\';
path[len + 1] = u'\0'; path[len + 1] = u'\0';
} }
/*
* chdir() seems flaky on windows 7
* in a similar way to rmdir() sigh
*/
for (err = errno, ms = 1;; ms *= 2) {
if (SetCurrentDirectory(path)) { if (SetCurrentDirectory(path)) {
/* /*
* Now we need to set a magic environment variable. * Now we need to set a magic environment variable.
@ -56,10 +45,9 @@ textwindows int sys_chdir_nt_impl(char16_t path[hasatleast PATH_MAX],
var[1] = path[0]; var[1] = path[0];
var[2] = ':'; var[2] = ':';
var[3] = 0; var[3] = 0;
if (!SetEnvironmentVariable(var, path)) { if (!SetEnvironmentVariable(var, path))
return __winerr(); return __winerr();
} }
}
return 0; return 0;
} else { } else {
return enametoolong(); return enametoolong();
@ -68,19 +56,9 @@ textwindows int sys_chdir_nt_impl(char16_t path[hasatleast PATH_MAX],
return __winerr(); return __winerr();
} }
} else { } else {
e = GetLastError(); return __fix_enotdir(__winerr(), path);
if (ms <= 512 &&
(e == kNtErrorFileNotFound || e == kNtErrorAccessDenied)) {
Sleep(ms);
errno = err;
continue;
} else {
break;
} }
} }
}
return __fix_enotdir(-1, path);
}
textwindows int sys_chdir_nt(const char *path) { textwindows int sys_chdir_nt(const char *path) {
int len; int len;

View file

@ -57,15 +57,14 @@ static textwindows bool IsDirectorySymlink(const char16_t *path) {
static textwindows int sys_rmdir_nt(const char16_t *path) { static textwindows int sys_rmdir_nt(const char16_t *path) {
int ms; int ms;
for (ms = 1;; ms *= 2) { for (ms = 1;; ms *= 2) {
if (RemoveDirectory(path)) { if (RemoveDirectory(path))
return 0; return 0;
}
// Files can linger, for absolutely no reason. // Files can linger, for absolutely no reason.
// Possibly some Windows Defender bug on Win7. // Possibly some Windows Defender bug on Win7.
// Sleep for up to one second w/ expo backoff. // Sleep for up to one second w/ expo backoff.
// Alternative is use Microsoft internal APIs. // Alternative is use Microsoft internal APIs.
// Never could have imagined it'd be this bad. // Never could have imagined it'd be this bad.
if (GetLastError() == kNtErrorDirNotEmpty && ms <= 2048) { if (GetLastError() == kNtErrorDirNotEmpty && ms <= 1024) {
Sleep(ms); Sleep(ms);
continue; continue;
} else { } else {