#ifdef _WIN32
#include <curl/curl.h>
+#ifdef BUILDING_LIBCURL
#include "system_win32.h"
+#else
+#include "version_win32.h"
+
+static LARGE_INTEGER s_freq;
+static bool s_isVistaOrGreater;
+
+/* For tool or tests, we must initialize before calling Curl_now() */
+void curlx_now_init(void)
+{
+ if(curlx_verify_windows_version(6, 0, 0, PLATFORM_WINNT,
+ VERSION_GREATER_THAN_EQUAL))
+ s_isVistaOrGreater = true;
+ else
+ s_isVistaOrGreater = false;
+
+ QueryPerformanceFrequency(&s_freq);
+}
+#endif
/* In case of bug fix this function has a counterpart in tool_util.c */
struct curltime Curl_now(void)
{
struct curltime now;
- if(Curl_isVistaOrGreater) { /* QPC timer might have issues pre-Vista */
+ bool isVistaOrGreater;
+#ifdef BUILDING_LIBCURL
+ isVistaOrGreater = Curl_isVistaOrGreater;
+#else
+ isVistaOrGreater = s_isVistaOrGreater;
+#endif
+ if(isVistaOrGreater) { /* QPC timer might have issues pre-Vista */
LARGE_INTEGER count;
+ LARGE_INTEGER freq;
+#ifdef BUILDING_LIBCURL
+ freq = Curl_freq;
+#else
+ freq = s_freq;
+#endif
+ DEBUGASSERT(freq.QuadPart);
QueryPerformanceCounter(&count);
- now.tv_sec = (time_t)(count.QuadPart / Curl_freq.QuadPart);
- now.tv_usec = (int)((count.QuadPart % Curl_freq.QuadPart) * 1000000 /
- Curl_freq.QuadPart);
+ now.tv_sec = (time_t)(count.QuadPart / freq.QuadPart);
+ now.tv_usec = (int)((count.QuadPart % freq.QuadPart) * 1000000 /
+ freq.QuadPart);
}
else {
/* Disable /analyze warning that GetTickCount64 is preferred */
#include "timediff.h"
+#ifndef BUILDING_LIBCURL
+/* this renames the functions so that the tool code can use the same code
+ without getting symbol collisions */
+#define Curl_now curlx_now
+#define Curl_timediff(a,b) curlx_timediff(a,b)
+#define Curl_timediff_ceil(a,b) curlx_timediff_ceil(a,b)
+#define Curl_timediff_us(a,b) curlx_timediff_us(a,b)
+
+/* For tool or tests, we must initialize before calling Curl_now() */
+void curlx_now_init(void);
+#endif
+
struct curltime {
time_t tv_sec; /* seconds */
int tv_usec; /* microseconds */
) else if "!var!" == "CURL_SRC_X_C_FILES" (
call :element %1 lib "strparse.c" %3
call :element %1 lib "strcase.c" %3
+ call :element %1 lib "timeval.c" %3
call :element %1 lib "nonblock.c" %3
call :element %1 lib "warnless.c" %3
call :element %1 lib "curl_multibyte.c" %3
call :element %1 lib "curl_setup.h" %3
call :element %1 lib "strparse.h" %3
call :element %1 lib "strcase.h" %3
+ call :element %1 lib "timeval.h" %3
call :element %1 lib "nonblock.h" %3
call :element %1 lib "warnless.h" %3
call :element %1 lib "curl_ctype.h" %3
# libcurl sources to include in curltool lib we use for test binaries
CURLTOOL_LIBCURL_CFILES = \
../lib/base64.c \
- ../lib/dynbuf.c
+ ../lib/dynbuf.c \
+ ../lib/timeval.c
# libcurl has sources that provide functions named curlx_* that are not part of
# the official API, but we reuse the code here to avoid duplication.
../lib/strparse.c \
../lib/strcase.c \
../lib/timediff.c \
+ ../lib/timeval.c \
../lib/version_win32.c \
../lib/warnless.c
../lib/strparse.h \
../lib/strcase.h \
../lib/timediff.h \
+ ../lib/timeval.h \
../lib/version_win32.h \
../lib/warnless.h
curl_off_t dltotal, curl_off_t dlnow,
curl_off_t ultotal, curl_off_t ulnow)
{
- struct timeval now = tvnow();
+ struct curltime now = curlx_now();
struct per_transfer *per = clientp;
struct OperationConfig *config = per->config;
struct ProgressData *bar = &per->progressbar;
if(bar->prev == point)
/* progress did not change since last invoke */
return 0;
- else if((tvdiff(now, bar->prevtime) < 100L) && point < total)
+ else if((curlx_timediff(now, bar->prevtime) < 100L) && point < total)
/* limit progress-bar updating to 10 Hz except when we are at 100% */
return 0;
}
else {
/* total is unknown */
- if(tvdiff(now, bar->prevtime) < 100L)
+ if(curlx_timediff(now, bar->prevtime) < 100L)
/* limit progress-bar updating to 10 Hz */
return 0;
update_width(bar);
struct ProgressData {
int calls;
curl_off_t prev;
- struct timeval prevtime;
+ struct curltime prevtime;
int width;
FILE *out; /* where to write everything to */
curl_off_t initial_size;
}
if(config->timeout_ms) {
- struct timeval now = tvnow();
- long msdelta = tvdiff(now, per->start);
+ struct curltime now = curlx_now();
+ long msdelta = (long)curlx_timediff(now, per->start);
if(msdelta > config->timeout_ms)
/* timeout */
if(config->readbusy) {
/* lame code to keep the rate down because the input might not deliver
anything, get paused again and come back here immediately */
- static long rate = 500;
- static struct timeval prev;
+ static timediff_t rate = 500;
+ static struct curltime prev;
static curl_off_t ulprev;
if(ulprev == ulnow) {
/* it did not upload anything since last call */
- struct timeval now = tvnow();
+ struct curltime now = curlx_now();
if(prev.tv_sec)
/* get a rolling average rate */
- /* rate = rate - rate/4 + tvdiff(now, prev)/4; */
- rate -= rate/4 - tvdiff(now, prev)/4;
+ rate -= rate/4 - curlx_timediff(now, prev)/4;
prev = now;
}
else {
struct OperationConfig *first;
struct OperationConfig *current;
struct OperationConfig *last;
- long ms_per_transfer; /* start next transfer after (at least) this
+ timediff_t ms_per_transfer; /* start next transfer after (at least) this
many milliseconds */
trace tracetype;
int progressmode; /* CURL_PROGRESS_BAR / CURL_PROGRESS_STATS */
}
#endif
-LARGE_INTEGER tool_freq;
-bool tool_isVistaOrGreater;
-
CURLcode win32_init(void)
{
- /* curlx_verify_windows_version must be called during init at least once
- because it has its own initialization routine. */
- if(curlx_verify_windows_version(6, 0, 0, PLATFORM_WINNT,
- VERSION_GREATER_THAN_EQUAL))
- tool_isVistaOrGreater = true;
- else
- tool_isVistaOrGreater = false;
-
- QueryPerformanceFrequency(&tool_freq);
-
+ curlx_now_init();
#if !defined(CURL_WINDOWS_UWP) && !defined(UNDER_CE)
init_terminal();
#endif
my_setopt_offt(per->curl, CURLOPT_INFILESIZE_LARGE, uploadfilesize);
}
per->uploadfilesize = uploadfilesize;
- per->start = tvnow();
+ per->start = curlx_now();
return result;
}
time */
if(per->retry_remaining &&
(!config->retry_maxtime ||
- (tvdiff(tvnow(), per->retrystart) <
+ (curlx_timediff(curlx_now(), per->retrystart) <
config->retry_maxtime*1000L)) ) {
enum {
RETRY_NO,
maximum time allowed for retrying, then exit the retries right
away */
if(config->retry_maxtime) {
- curl_off_t seconds = tvdiff(tvnow(), per->retrystart)/1000;
+ curl_off_t seconds = curlx_timediff(curlx_now(),
+ per->retrystart)/1000;
if((CURL_OFF_T_MAX - retry_after < seconds) ||
(seconds + retry_after > config->retry_maxtime)) {
config->retry_delay*1000L : RETRY_SLEEP_DEFAULT; /* ms */
per->retry_remaining = config->req_retry;
per->retry_sleep = per->retry_sleep_default; /* ms */
- per->retrystart = tvnow();
+ per->retrystart = curlx_now();
state->li++;
/* Here's looping around each globbed URL */
CURLMcode mcode;
CURLcode result;
int still_running;
- struct timeval start;
+ struct curltime start;
bool more_transfers;
bool added_transfers;
/* wrapitup is set TRUE after a critical error occurs to end all transfers */
s->mcode = CURLM_OK;
s->result = CURLE_OK;
s->still_running = 1;
- s->start = tvnow();
+ s->start = curlx_now();
s->wrapitup = FALSE;
s->wrapitup_processed = FALSE;
s->tick = time(NULL);
bool retry;
long delay_ms;
bool bailout = FALSE;
- struct timeval start;
+ struct curltime start;
- start = tvnow();
+ start = curlx_now();
if(!per->skip) {
result = pre_transfer(global, per);
if(result)
if(per && global->ms_per_transfer) {
/* how long time did the most recent transfer take in number of
milliseconds */
- long milli = tvdiff(tvnow(), start);
+ timediff_t milli = curlx_timediff(curlx_now(), start);
if(milli < global->ms_per_transfer) {
- notef(global, "Transfer took %ld ms, waits %ldms as set by --rate",
- milli, global->ms_per_transfer - milli);
+ notef(global, "Transfer took %" CURL_FORMAT_CURL_OFF_T " ms, "
+ "waits %ldms as set by --rate",
+ milli, (long)(global->ms_per_transfer - milli));
/* The transfer took less time than wanted. Wait a little. */
- tool_go_sleep(global->ms_per_transfer - milli);
+ tool_go_sleep((long)(global->ms_per_transfer - milli));
}
}
}
long retry_sleep_default;
long retry_sleep;
long num_retries; /* counts the performed retries */
- struct timeval start; /* start of this transfer */
- struct timeval retrystart;
+ struct curltime start; /* start of this transfer */
+ struct curltime retrystart;
char *url;
unsigned int urlnum; /* the index of the given URL */
char *outfile;
struct speedcount {
curl_off_t dl;
curl_off_t ul;
- struct timeval stamp;
+ struct curltime stamp;
};
#define SPEEDCNT 10
static unsigned int speedindex;
| 6 -- 9.9G 0 2 2 0:00:40 0:00:02 0:00:37 4087M
*/
bool progress_meter(struct GlobalConfig *global,
- struct timeval *start,
+ struct curltime *start,
bool final)
{
- static struct timeval stamp;
+ static struct curltime stamp;
static bool header = FALSE;
- struct timeval now;
- long diff;
+ struct curltime now;
+ timediff_t diff;
if(global->noprogress || global->silent)
return FALSE;
- now = tvnow();
- diff = tvdiff(now, stamp);
+ now = curlx_now();
+ diff = curlx_timediff(now, stamp);
if(!header) {
header = TRUE;
char time_total[10];
char time_spent[10];
char buffer[3][6];
- curl_off_t spent = tvdiff(now, *start)/1000;
+ curl_off_t spent = curlx_timediff(now, *start)/1000;
char dlpercen[4]="--";
char ulpercen[4]="--";
struct per_transfer *per;
}
{
- long deltams;
+ timediff_t deltams;
curl_off_t dl;
curl_off_t ul;
curl_off_t dls;
curl_off_t uls;
if(indexwrapped) {
/* 'speedindex' is the oldest stored data */
- deltams = tvdiff(now, speedstore[speedindex].stamp);
+ deltams = curlx_timediff(now, speedstore[speedindex].stamp);
dl = all_dlnow - speedstore[speedindex].dl;
ul = all_ulnow - speedstore[speedindex].ul;
}
else {
/* since the beginning */
- deltams = tvdiff(now, *start);
+ deltams = curlx_timediff(now, *start);
dl = all_dlnow;
ul = all_ulnow;
}
curl_off_t ulnow);
bool progress_meter(struct GlobalConfig *global,
- struct timeval *start,
+ struct curltime *start,
bool final);
void progress_finalize(struct per_transfer *per);
#include <curl/curl.h> /* external interface */
+#include "timeval.h"
+
/*
* Platform specific stuff.
*/
#endif
#ifdef _WIN32
-/* set in win32_init() */
-extern LARGE_INTEGER tool_freq;
-extern bool tool_isVistaOrGreater;
/* set in init_terminal() */
extern bool tool_term_has_bold;
#ifdef _WIN32
-/* In case of bug fix this function has a counterpart in timeval.c */
-struct timeval tvnow(void)
-{
- struct timeval now;
- if(tool_isVistaOrGreater) { /* QPC timer might have issues pre-Vista */
- LARGE_INTEGER count;
- QueryPerformanceCounter(&count);
- now.tv_sec = (long)(count.QuadPart / tool_freq.QuadPart);
- now.tv_usec = (long)((count.QuadPart % tool_freq.QuadPart) * 1000000 /
- tool_freq.QuadPart);
- }
- else {
- /* Disable /analyze warning that GetTickCount64 is preferred */
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable:28159)
-#endif
- DWORD milliseconds = GetTickCount();
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
- now.tv_sec = (long)(milliseconds / 1000);
- now.tv_usec = (long)((milliseconds % 1000) * 1000);
- }
- return now;
-}
-
-#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC)
-
-struct timeval tvnow(void)
-{
- /*
- ** clock_gettime() is granted to be increased monotonically when the
- ** monotonic clock is queried. Time starting point is unspecified, it
- ** could be the system start-up time, the Epoch, or something else,
- ** in any case the time starting point does not change once that the
- ** system has started up.
- */
- struct timeval now;
- struct timespec tsnow;
- if(0 == clock_gettime(CLOCK_MONOTONIC, &tsnow)) {
- now.tv_sec = tsnow.tv_sec;
- now.tv_usec = (int)(tsnow.tv_nsec / 1000);
- }
- /*
- ** Even when the configure process has truly detected monotonic clock
- ** availability, it might happen that it is not actually available at
- ** runtime. When this occurs simply fallback to other time source.
- */
-#ifdef HAVE_GETTIMEOFDAY
- else
- (void)gettimeofday(&now, NULL);
-#else
- else {
- now.tv_sec = time(NULL);
- now.tv_usec = 0;
- }
-#endif
- return now;
-}
-
-#elif defined(HAVE_GETTIMEOFDAY)
-
-struct timeval tvnow(void)
-{
- /*
- ** gettimeofday() is not granted to be increased monotonically, due to
- ** clock drifting and external source time synchronization it can jump
- ** forward or backward in time.
- */
- struct timeval now;
- (void)gettimeofday(&now, NULL);
- return now;
-}
-
-#else
-
-struct timeval tvnow(void)
-{
- /*
- ** time() returns the value of time in seconds since the Epoch.
- */
- struct timeval now;
- now.tv_sec = time(NULL);
- now.tv_usec = 0;
- return now;
-}
-
-#endif
-
-#ifdef _WIN32
-
struct timeval tvrealnow(void)
{
/* UNIX EPOCH (1970-01-01) in FILETIME (1601-01-01) as 64-bit value */
#endif
-/*
- * Make sure that the first argument is the more recent time, as otherwise
- * we will get a weird negative time-diff back...
- *
- * Returns: the time difference in number of milliseconds.
- */
-long tvdiff(struct timeval newer, struct timeval older)
-{
- return (long)(newer.tv_sec-older.tv_sec)*1000+
- (long)(newer.tv_usec-older.tv_usec)/1000;
-}
-
/* Case insensitive compare. Accept NULL pointers. */
int struplocompare(const char *p1, const char *p2)
{
***************************************************************************/
#include "tool_setup.h"
-/**
- * Return timeval of the MONOTONIC timer, depending on platform
- * this may be completely unrelated to the REALTIME.
- */
-struct timeval tvnow(void);
-
/**
* Return timeval of the REALTIME clock.
*/
struct timeval tvrealnow(void);
-/*
- * Make sure that the first argument (t1) is the more recent time and t2 is
- * the older time, as otherwise you get a weird negative time-diff back...
- *
- * Returns: the time difference in number of milliseconds.
- */
-long tvdiff(struct timeval t1, struct timeval t2);
-
/* Case insensitive comparison support. */
int struplocompare(const char *p1, const char *p2);
int struplocompare4sort(const void *p1, const void *p2);
../../lib/strequal.c \
../../lib/warnless.c \
../../lib/timediff.c \
+ ../../lib/timeval.c \
../../lib/dynbuf.c \
- ../../lib/strdup.c \
../../lib/strcase.c \
+ ../../lib/strdup.c \
../../lib/curl_get_line.c \
- ../../lib/curl_multibyte.c
+ ../../lib/curl_multibyte.c \
+ ../../lib/version_win32.c
CURLX_HDRS = \
../../lib/curlx.h \
+ ../../lib/curl_ctype.h \
../../lib/nonblock.h \
../../lib/strcase.h \
../../lib/warnless.h \
../../lib/timediff.h \
- ../../lib/curl_ctype.h \
+ ../../lib/timeval.h \
../../lib/dynbuf.h \
../../lib/strcase.h \
../../lib/strdup.h \
../../lib/curl_get_line.h \
- ../../lib/curl_multibyte.h
+ ../../lib/curl_multibyte.h \
+ ../../lib/version_win32.h
UTIL = \
getpart.c \
const char *socket_type = "IPv4";
int socket_domain = AF_INET;
-static struct timeval tvnow(void);
-
/* This function returns a pointer to STATIC memory. It converts the given
* binary lump to a hex formatted string usable for output in logs or
* whatever.
va_list ap;
char buffer[2048 + 1];
FILE *logfp;
- struct timeval tv;
+ struct curltime tv;
time_t sec;
struct tm *now;
char timebuf[20];
return;
}
- tv = tvnow();
+ tv = curlx_now();
if(!known_offset) {
epoch_offset = time(NULL) - tv.tv_sec;
known_offset = 1;
int win32_init(void)
{
+ curlx_now_init();
#ifdef USE_WINSOCK
- WORD wVersionRequested;
- WSADATA wsaData;
- int err;
+ {
+ WORD wVersionRequested;
+ WSADATA wsaData;
+ int err;
- wVersionRequested = MAKEWORD(2, 2);
- err = WSAStartup(wVersionRequested, &wsaData);
+ wVersionRequested = MAKEWORD(2, 2);
+ err = WSAStartup(wVersionRequested, &wsaData);
- if(err) {
- win32_perror("Winsock init failed");
- logmsg("Error initialising Winsock -- aborting");
- return 1;
- }
+ if(err) {
+ win32_perror("Winsock init failed");
+ logmsg("Error initialising Winsock -- aborting");
+ return 1;
+ }
- if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) ||
- HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested) ) {
- WSACleanup();
- win32_perror("Winsock init failed");
- logmsg("No suitable winsock.dll found -- aborting");
- return 1;
+ if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) ||
+ HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested) ) {
+ WSACleanup();
+ win32_perror("Winsock init failed");
+ logmsg("No suitable winsock.dll found -- aborting");
+ return 1;
+ }
}
#endif /* USE_WINSOCK */
atexit(win32_cleanup);
filename, error, strerror(error));
}
-
-#ifdef _WIN32
-
-static struct timeval tvnow(void)
-{
- /*
- ** GetTickCount() is available on _all_ Windows versions from W95 up
- ** to nowadays. Returns milliseconds elapsed since last system boot,
- ** increases monotonically and wraps once 49.7 days have elapsed.
- **
- ** GetTickCount64() is available on Windows version from Windows Vista
- ** and Windows Server 2008 up to nowadays. The resolution of the
- ** function is limited to the resolution of the system timer, which
- ** is typically in the range of 10 milliseconds to 16 milliseconds.
- */
- struct timeval now;
-#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)
- ULONGLONG milliseconds = GetTickCount64();
-#else
- DWORD milliseconds = GetTickCount();
-#endif
- now.tv_sec = (long)(milliseconds / 1000);
- now.tv_usec = (long)((milliseconds % 1000) * 1000);
- return now;
-}
-
-#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC)
-
-static struct timeval tvnow(void)
-{
- /*
- ** clock_gettime() is granted to be increased monotonically when the
- ** monotonic clock is queried. Time starting point is unspecified, it
- ** could be the system start-up time, the Epoch, or something else,
- ** in any case the time starting point does not change once that the
- ** system has started up.
- */
- struct timeval now;
- struct timespec tsnow;
- if(0 == clock_gettime(CLOCK_MONOTONIC, &tsnow)) {
- now.tv_sec = tsnow.tv_sec;
- now.tv_usec = (int)(tsnow.tv_nsec / 1000);
- }
- /*
- ** Even when the configure process has truly detected monotonic clock
- ** availability, it might happen that it is not actually available at
- ** run-time. When this occurs simply fallback to other time source.
- */
-#ifdef HAVE_GETTIMEOFDAY
- else
- (void)gettimeofday(&now, NULL);
-#else
- else {
- now.tv_sec = time(NULL);
- now.tv_usec = 0;
- }
-#endif
- return now;
-}
-
-#elif defined(HAVE_GETTIMEOFDAY)
-
-static struct timeval tvnow(void)
-{
- /*
- ** gettimeofday() is not granted to be increased monotonically, due to
- ** clock drifting and external source time synchronization it can jump
- ** forward or backward in time.
- */
- struct timeval now;
- (void)gettimeofday(&now, NULL);
- return now;
-}
-
-#else
-
-static struct timeval tvnow(void)
-{
- /*
- ** time() returns the value of time in seconds since the Epoch.
- */
- struct timeval now;
- now.tv_sec = time(NULL);
- now.tv_usec = 0;
- return now;
-}
-
-#endif
-
/* vars used to keep around previous signal handlers */
typedef void (*SIGHANDLER_T)(int);
/* fopens the test case file */
FILE *test2fopen(long testno, const char *logdir);
-#include "timediff.h"
+#include "timeval.h"
int wait_ms(timediff_t timeout_ms);
curl_off_t our_getpid(void);
$(CURL_DIROBJ)\nonblock.obj \
$(CURL_DIROBJ)\strparse.obj \
$(CURL_DIROBJ)\strcase.obj \
+ $(CURL_DIROBJ)\timeval.obj \
$(CURL_DIROBJ)\warnless.obj \
$(CURL_DIROBJ)\curl_get_line.obj \
$(CURL_DIROBJ)\curl_multibyte.obj \
$(CURL_CC) $(CURL_CFLAGS) /Fo"$@" ../lib/strparse.c
$(CURL_DIROBJ)\strcase.obj: ../lib/strcase.c
$(CURL_CC) $(CURL_CFLAGS) /Fo"$@" ../lib/strcase.c
+$(CURL_DIROBJ)\timeval.obj: ../lib/timeval.c
+ $(CURL_CC) $(CURL_CFLAGS) /Fo"$@" ../lib/timeval.c
$(CURL_DIROBJ)\warnless.obj: ../lib/warnless.c
$(CURL_CC) $(CURL_CFLAGS) /Fo"$@" ../lib/warnless.c
$(CURL_DIROBJ)\curl_get_line.obj: ../lib/curl_get_line.c