diff --git a/CMakeLists.txt b/CMakeLists.txt index e6e0d691..9fef51ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -275,18 +275,12 @@ if (WIN32) list(APPEND HDR_PUBLIC ${WIN32_HELPERS_PATH}/websock-w32.h - ${WIN32_HELPERS_PATH}/gettimeofday.h ) - if (MINGW) - list(APPEND SOURCES - ${WIN32_HELPERS_PATH}/gettimeofday.c - ) - else(MINGW) + if (NOT MINGW) list(APPEND SOURCES ${WIN32_HELPERS_PATH}/websock-w32.c - ${WIN32_HELPERS_PATH}/gettimeofday.c ) - endif(MINGW) + endif() include_directories(${WIN32_HELPERS_PATH}) else(WIN32) # Unix. diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c index 1542deae..458a5479 100644 --- a/lib/libwebsockets.c +++ b/lib/libwebsockets.c @@ -110,6 +110,35 @@ lws_get_library_version(void) return library_version; } +static unsigned long long time_in_microseconds() +{ +#if defined(WIN32) || defined(_WIN32) +#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL + FILETIME filetime; + ULARGE_INTEGER datetime; + +#ifdef _WIN32_WCE + GetCurrentFT(&filetime); +#else + GetSystemTimeAsFileTime(&filetime); +#endif + + /* + * As per Windows documentation for FILETIME, copy the resulting FILETIME structure to a + * ULARGE_INTEGER structure using memcpy (using memcpy instead of direct assignment can + * prevent alignment faults on 64-bit Windows). + */ + memcpy(&datetime, &filetime, sizeof(datetime)); + + /* Windows file times are in 100s of nanoseconds. */ + return (datetime.QuadPart - DELTA_EPOCH_IN_MICROSECS) / 10; +#else + struct timeval tv; + gettimeofday(&tv, NULL); + return (tv.tv_sec * 1000000) + tv.tv_usec; +#endif +} + int insert_wsi_socket_into_fds(struct libwebsocket_context *context, struct libwebsocket *wsi) @@ -915,7 +944,7 @@ libwebsocket_service_fd(struct libwebsocket_context *context, int n; int m; int listen_socket_fds_index = 0; - struct timeval tv; + time_t now; int timed_out = 0; int our_fd = 0; char draining_flow = 0; @@ -935,10 +964,10 @@ libwebsocket_service_fd(struct libwebsocket_context *context, * it returns immediately then. */ - gettimeofday(&tv, NULL); + time(&now); - if (context->last_timeout_check_s != tv.tv_sec) { - context->last_timeout_check_s = tv.tv_sec; + if (context->last_timeout_check_s != now) { + context->last_timeout_check_s = now; #ifndef WIN32 /* if our parent went down, don't linger around */ @@ -958,8 +987,7 @@ libwebsocket_service_fd(struct libwebsocket_context *context, if (!wsi) continue; - if (libwebsocket_service_timeout_check(context, wsi, - tv.tv_sec)) + if (libwebsocket_service_timeout_check(context, wsi, now)) /* he did time out... */ if (m == our_fd) { /* it was the guy we came to service! */ @@ -1613,11 +1641,11 @@ LWS_VISIBLE void libwebsocket_set_timeout(struct libwebsocket *wsi, enum pending_timeout reason, int secs) { - struct timeval tv; + time_t now; - gettimeofday(&tv, NULL); + time(&now); - wsi->pending_timeout_limit = tv.tv_sec + secs; + wsi->pending_timeout_limit = now + secs; wsi->pending_timeout = reason; } @@ -1641,13 +1669,10 @@ void lws_latency(struct libwebsocket_context *context, struct libwebsocket *wsi, const char *action, int ret, int completed) { - struct timeval tv; - unsigned long u; + unsigned long long u; char buf[256]; - gettimeofday(&tv, NULL); - - u = (tv.tv_sec * 1000000) + tv.tv_usec; + u = time_in_microseconds(); if (action) { if (completed) { @@ -2566,16 +2591,15 @@ libwebsocket_ensure_user_space(struct libwebsocket *wsi) static void lwsl_emit_stderr(int level, const char *line) { char buf[300]; - struct timeval tv; + unsigned long long now; int n; - gettimeofday(&tv, NULL); - buf[0] = '\0'; for (n = 0; n < LLL_COUNT; n++) if (level == (1 << n)) { - sprintf(buf, "[%ld:%04d] %s: ", tv.tv_sec, - (int)(tv.tv_usec / 100), log_level_names[n]); + now = time_in_microseconds() / 100; + sprintf(buf, "[%lu:%04d] %s: ", (unsigned long) now / 10000, + (int)(now % 10000), log_level_names[n]); break; } diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index b3c7f082..24856a49 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -38,8 +38,6 @@ extern "C" { #include #include "websock-w32.h" -#include "gettimeofday.h" - #define strcasecmp stricmp #define getdtablesize() 30000 diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index 87c85f4a..f9df4a64 100644 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -264,7 +264,7 @@ struct libwebsocket_context { char canonical_hostname[128]; unsigned int http_proxy_port; unsigned int options; - unsigned long last_timeout_check_s; + time_t last_timeout_check_s; /* * usable by anything in the service code, but only if the scope @@ -406,7 +406,7 @@ struct libwebsocket { unsigned int hdr_parsing_completed:1; char pending_timeout; /* enum pending_timeout */ - unsigned long pending_timeout_limit; + time_t pending_timeout_limit; int sock; int position_in_fds_table;