mirror of https://github.com/postgres/postgres
1. Update our open() wrapper to check for NT's STATUS_DELETE_PENDING and translate it to Unix-like errors. This is done with RtlGetLastNtStatus(), which is dynamically loaded from ntdll. A new file win32ntdll.c centralizes lookup of NT functions, in case we decide to add more in the future. 2. Remove non-working code that was trying to do something similar for stat(), and just reuse the open() wrapper code. As a side effect, stat() also gains resilience against "sharing violation" errors. 3. Since stat() is used very early in process startup, remove the requirement that the Win32 signal event has been created before pgwin32_open_handle() is reached. Instead, teach pg_usleep() to fall back to a non-interruptible sleep if reached before the signal event is available. This could be back-patched, but for now it's in master only. The problem has apparently been with us for a long time and generated only a few complaints. Proposed patches trigger it more often, which led to this investigation and fix. Reviewed-by: Andres Freund <andres@anarazel.de> Reviewed-by: Alexander Lakhin <exclusion@gmail.com> Reviewed-by: Juan José Santamaría Flecha <juanjo.santamaria@gmail.com> Discussion: https://postgr.es/m/CA%2BhUKGJz_pZTF9mckn6XgSv69%2BjGwdgLkxZ6b3NWGLBCVjqUZA%40mail.gmail.compull/138/head
parent
5d08137076
commit
e2f0f8ed25
@ -0,0 +1,27 @@ |
||||
/*-------------------------------------------------------------------------
|
||||
* |
||||
* win32ntdll.h |
||||
* Dynamically loaded Windows NT functions. |
||||
* |
||||
* Portions Copyright (c) 2021, PostgreSQL Global Development Group |
||||
* Portions Copyright (c) 1994, Regents of the University of California |
||||
* |
||||
* src/include/port/win32ntdll.h |
||||
* |
||||
*------------------------------------------------------------------------- |
||||
*/ |
||||
|
||||
/*
|
||||
* Because this includes NT headers that normally conflict with Win32 headers, |
||||
* any translation unit that includes it should #define UMDF_USING_NTSTATUS |
||||
* before including <windows.h>. |
||||
*/ |
||||
|
||||
#include <ntstatus.h> |
||||
#include <winternl.h> |
||||
|
||||
typedef NTSTATUS (__stdcall *RtlGetLastNtStatus_t) (void); |
||||
|
||||
extern RtlGetLastNtStatus_t pg_RtlGetLastNtStatus; |
||||
|
||||
extern int initialize_ntdll(void); |
@ -0,0 +1,69 @@ |
||||
/*-------------------------------------------------------------------------
|
||||
* |
||||
* win32ntdll.c |
||||
* Dynamically loaded Windows NT functions. |
||||
* |
||||
* Portions Copyright (c) 2021, PostgreSQL Global Development Group |
||||
* Portions Copyright (c) 1994, Regents of the University of California |
||||
* |
||||
* |
||||
* IDENTIFICATION |
||||
* src/port/win32ntdll.c |
||||
* |
||||
*------------------------------------------------------------------------- |
||||
*/ |
||||
|
||||
#define UMDF_USING_NTSTATUS |
||||
|
||||
#include "c.h" |
||||
|
||||
#include "port/win32ntdll.h" |
||||
|
||||
RtlGetLastNtStatus_t pg_RtlGetLastNtStatus; |
||||
|
||||
typedef struct NtDllRoutine |
||||
{ |
||||
const char *name; |
||||
pg_funcptr_t *address; |
||||
} NtDllRoutine; |
||||
|
||||
static const NtDllRoutine routines[] = { |
||||
{"RtlGetLastNtStatus", (pg_funcptr_t *) &pg_RtlGetLastNtStatus} |
||||
}; |
||||
|
||||
static bool initialized; |
||||
|
||||
int |
||||
initialize_ntdll(void) |
||||
{ |
||||
HMODULE module; |
||||
|
||||
if (initialized) |
||||
return 0; |
||||
|
||||
if (!(module = LoadLibraryEx("ntdll.dll", NULL, 0))) |
||||
{ |
||||
_dosmaperr(GetLastError()); |
||||
return -1; |
||||
} |
||||
|
||||
for (int i = 0; i < lengthof(routines); ++i) |
||||
{ |
||||
pg_funcptr_t address; |
||||
|
||||
address = (pg_funcptr_t) GetProcAddress(module, routines[i].name); |
||||
if (!address) |
||||
{ |
||||
_dosmaperr(GetLastError()); |
||||
FreeLibrary(module); |
||||
|
||||
return -1; |
||||
} |
||||
|
||||
*(pg_funcptr_t *) routines[i].address = address; |
||||
} |
||||
|
||||
initialized = true; |
||||
|
||||
return 0; |
||||
} |
Loading…
Reference in new issue