Replace g_time3() with g_get_elapsed_ms()

The function as specified used gettimeofday() which is susceptible
to manual time changes, and is obsoleted in POSIX.1-2008. The
replacement uses clock_gettime(CLOCK_MONOTONIC, ) which is not
susceptible to manual time changes (at least on Linux) and cannot run
backwards.

Also, on systems with 32-bit integers, the value returned by this
function wraps around every 49.7 days. To cope with a wraparound in
a way compliant with the C standard, this value needs to return an
unsigned integer type rather than a signed integer type.
This commit is contained in:
matt335672
2024-12-04 11:13:29 +00:00
parent 90798cdeaa
commit 1f79eb1c01
10 changed files with 69 additions and 58 deletions
+13 -11
View File
@@ -3764,19 +3764,21 @@ g_check_user_in_group(const char *username, int gid, int *ok)
#endif // HAVE_GETGROUPLIST
/*****************************************************************************/
/* returns time in milliseconds, uses gettimeofday
does not work in win32 */
int
g_time3(void)
unsigned int
g_get_elapsed_ms(void)
{
#if defined(_WIN32)
return 0;
#else
struct timeval tp;
unsigned int result = 0;
struct timespec tp;
gettimeofday(&tp, 0);
return (tp.tv_sec * 1000) + (tp.tv_usec / 1000);
#endif
if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
{
result = (unsigned int)tp.tv_sec * 1000;
// POSIX 1003.1-2004 specifies that tv_nsec is a long (i.e. a
// signed type), but can only contain [0..999,999,999]
result += tp.tv_nsec / 1000000;
}
return result;
}
/******************************************************************************/
+20 -1
View File
@@ -393,7 +393,26 @@ int g_getgroup_info(const char *groupname, int *gid);
* Primary group of username is also checked
*/
int g_check_user_in_group(const char *username, int gid, int *ok);
int g_time3(void);
/**
* Gets elapsed milliseconds since some arbitrary point in the past
*
* The returned value is unaffected by leap-seconds or time zone changes.
*
* @return elaped ms since some arbitrary point
*
* Calculate the duration of a task by calling this routine before and
* after the task, and subtracting the two values.
*
* The value wraps every so often (every 49.7 days on a 32-bit system),
* but as we are using unsigned arithmetic, the difference of any of these
* two values can be used to calculate elapsed time, whether-or-not a wrap
* occurs during the interval - provided of course the time being measured
* is less than the total wrap-around interval.
*/
unsigned int
g_get_elapsed_ms(void);
int g_save_to_bmp(const char *filename, char *data, int stride_bytes,
int width, int height, int depth, int bits_per_pixel);
void *g_shmat(int shmid);
+6 -6
View File
@@ -696,7 +696,7 @@ local_connect_shim(int fd, const char *server, const char *port)
/**************************************************************************//**
* Waits for an asynchronous connect to complete.
* @param self - Transport object
* @param start_time Start time of connect (from g_time3())
* @param start_time Start time of connect (from g_get_elapsed_ms())
* @param timeout Total wait timeout
* @return 0 - connect succeeded, 1 - Connect failed
*
@@ -704,10 +704,10 @@ local_connect_shim(int fd, const char *server, const char *port)
* on a regular basis.
*/
static int
poll_for_async_connect(struct trans *self, int start_time, int timeout)
poll_for_async_connect(struct trans *self, unsigned int start_time, int timeout)
{
int rv = 1;
int ms_remaining = timeout - (g_time3() - start_time);
int ms_remaining = timeout - (int)(g_get_elapsed_ms() - start_time);
while (ms_remaining > 0)
{
@@ -736,7 +736,7 @@ poll_for_async_connect(struct trans *self, int start_time, int timeout)
break;
}
ms_remaining = timeout - (g_time3() - start_time);
ms_remaining = timeout - (int)(g_get_elapsed_ms() - start_time);
}
return rv;
}
@@ -747,7 +747,7 @@ int
trans_connect(struct trans *self, const char *server, const char *port,
int timeout)
{
int start_time = g_time3();
unsigned int start_time = g_get_elapsed_ms();
int error;
int ms_before_next_connect;
@@ -826,7 +826,7 @@ trans_connect(struct trans *self, const char *server, const char *port,
}
/* Have we reached the total timeout yet? */
int ms_left = timeout - (g_time3() - start_time);
int ms_left = timeout - (int)(g_get_elapsed_ms() - start_time);
if (ms_left <= 0)
{
error = 1;