Skip to content

Commit 24c3ce8

Browse files
committed
Simplify gettimeofday for Windows.
Previously we bothered to forward-declare struct timezone, following man pages on typical systems, but POSIX actually says the argument (which we ignore anyway) is void *. Drop a line. While here, add an assertion that nobody actually uses the tzp argument. Previously we did extra work to select between Windows APIs needed on older releases, but now we can just use the higher resolution function directly. Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://postgr.es/m/CA%2BhUKGKwRpvGfcfq2qNVAQS2Wg1B9eA9QRhAmVSyJt1zsCN2sQ%40mail.gmail.com
1 parent 5c7121b commit 24c3ce8

File tree

2 files changed

+14
-58
lines changed

2 files changed

+14
-58
lines changed

src/include/port/win32_port.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,11 +179,10 @@
179179
#define SIGUSR1 30
180180
#define SIGUSR2 31
181181

182-
/* MinW has gettimeofday(), but MSVC doesn't */
182+
/* MinGW has gettimeofday(), but MSVC doesn't */
183183
#ifdef _MSC_VER
184-
struct timezone;
185184
/* Last parameter not used */
186-
extern int gettimeofday(struct timeval *tp, struct timezone *tzp);
185+
extern int gettimeofday(struct timeval *tp, void *tzp);
187186
#endif
188187

189188
/* for setitimer in backend/port/win32/timer.c */

src/port/win32gettimeofday.c

Lines changed: 12 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828

2929
#include "c.h"
3030

31+
#include <sysinfoapi.h>
32+
3133
#include <sys/time.h>
3234

3335
/* FILETIME of Jan 1 1970 00:00:00, the PostgreSQL epoch */
@@ -40,59 +42,6 @@ static const unsigned __int64 epoch = UINT64CONST(116444736000000000);
4042
#define FILETIME_UNITS_PER_SEC 10000000L
4143
#define FILETIME_UNITS_PER_USEC 10
4244

43-
/*
44-
* Both GetSystemTimeAsFileTime and GetSystemTimePreciseAsFileTime share a
45-
* signature, so we can just store a pointer to whichever we find. This
46-
* is the pointer's type.
47-
*/
48-
typedef VOID(WINAPI * PgGetSystemTimeFn) (LPFILETIME);
49-
50-
/* One-time initializer function, must match that signature. */
51-
static void WINAPI init_gettimeofday(LPFILETIME lpSystemTimeAsFileTime);
52-
53-
/* Storage for the function we pick at runtime */
54-
static PgGetSystemTimeFn pg_get_system_time = &init_gettimeofday;
55-
56-
/*
57-
* One time initializer. Determine whether GetSystemTimePreciseAsFileTime
58-
* is available and if so, plan to use it; if not, fall back to
59-
* GetSystemTimeAsFileTime.
60-
*/
61-
static void WINAPI
62-
init_gettimeofday(LPFILETIME lpSystemTimeAsFileTime)
63-
{
64-
/*
65-
* Because it's guaranteed that kernel32.dll will be linked into our
66-
* address space already, we don't need to LoadLibrary it and worry about
67-
* closing it afterwards, so we're not using Pg's dlopen/dlsym() wrapper.
68-
*
69-
* We'll just look up the address of GetSystemTimePreciseAsFileTime if
70-
* present.
71-
*
72-
* While we could look up the Windows version and skip this on Windows
73-
* versions below Windows 8 / Windows Server 2012 there isn't much point,
74-
* and determining the windows version is its self somewhat Windows
75-
* version and development SDK specific...
76-
*/
77-
pg_get_system_time = (PgGetSystemTimeFn) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),
78-
"GetSystemTimePreciseAsFileTime");
79-
if (pg_get_system_time == NULL)
80-
{
81-
/*
82-
* The expected error from GetLastError() is ERROR_PROC_NOT_FOUND, if
83-
* the function isn't present. No other error should occur.
84-
*
85-
* We can't report an error here because this might be running in
86-
* frontend code; and even if we're in the backend, it's too early to
87-
* elog(...) if we get some unexpected error. Also, it's not a
88-
* serious problem, so just silently fall back to
89-
* GetSystemTimeAsFileTime irrespective of why the failure occurred.
90-
*/
91-
pg_get_system_time = &GetSystemTimeAsFileTime;
92-
}
93-
94-
(*pg_get_system_time) (lpSystemTimeAsFileTime);
95-
}
9645

9746
/*
9847
* timezone information is stored outside the kernel so tzp isn't used anymore.
@@ -101,12 +50,20 @@ init_gettimeofday(LPFILETIME lpSystemTimeAsFileTime)
10150
* elapsed_time().
10251
*/
10352
int
104-
gettimeofday(struct timeval *tp, struct timezone *tzp)
53+
gettimeofday(struct timeval *tp, void *tzp)
10554
{
10655
FILETIME file_time;
10756
ULARGE_INTEGER ularge;
10857

109-
(*pg_get_system_time) (&file_time);
58+
/*
59+
* POSIX declines to define what tzp points to, saying "If tzp is not a
60+
* null pointer, the behavior is unspecified". Let's take this
61+
* opportunity to verify that noplace in Postgres tries to use any
62+
* unportable behavior.
63+
*/
64+
Assert(tzp == NULL);
65+
66+
GetSystemTimePreciseAsFileTime(&file_time);
11067
ularge.LowPart = file_time.dwLowDateTime;
11168
ularge.HighPart = file_time.dwHighDateTime;
11269

0 commit comments

Comments
 (0)