clock: Fix 32 bit assertions in GST_TIME_TO_TIMEVAL and GST_TIME_TO_TIMESPEC

On various 32 bit systems, time_t is actually 64 bits while long is
still only 32 bits. The macro would wrongly trigger its assertion in
this case if a value with more than 68 years worth of seconds is
converted.

Examples are various newer 32 bit platforms and old ones that are
compiled with -D_TIME_BITS=64.

Also statically assert that time_t is either 32 or 64 bits. Other values
might need adjustments in the macro.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6869>
This commit is contained in:
Sebastian Dröge 2024-05-17 11:03:51 +03:00 committed by GStreamer Marge Bot
parent d1c81cbd79
commit 562cecaef4
2 changed files with 28 additions and 20 deletions

View file

@ -43947,9 +43947,10 @@ printf("%" GST_TIME_FORMAT "\n", GST_TIME_ARGS(ts));
<function-macro name="TIME_TO_TIMEVAL" c:identifier="GST_TIME_TO_TIMEVAL" introspectable="0">
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstclock.h">Converts a #GstClockTime to a GTimeVal
&gt; on 32-bit systems, a timeval has a range of only 2^32 - 1 seconds,
&gt; which is about 68 years. Expect trouble if you want to schedule stuff
&gt; in your pipeline for 2038.</doc>
&gt; on many 32-bit systems, a timeval has a range of only 2^32 - 1 seconds,
&gt; which is about 68 years. Expect trouble if you want to schedule stuff
&gt; in your pipeline for 2038. This macro asserts that this case does not
&gt; happen.</doc>
<source-position filename="../subprojects/gstreamer/gst/gstclock.h"/>
<parameters>
<parameter name="t">

View file

@ -175,18 +175,22 @@ typedef gpointer GstClockID;
*
* Converts a #GstClockTime to a GTimeVal
*
* > on 32-bit systems, a timeval has a range of only 2^32 - 1 seconds,
* > which is about 68 years. Expect trouble if you want to schedule stuff
* > in your pipeline for 2038.
* > on many 32-bit systems, a timeval has a range of only 2^32 - 1 seconds,
* > which is about 68 years. Expect trouble if you want to schedule stuff
* > in your pipeline for 2038. This macro asserts that this case does not
* > happen.
*/
#define GST_TIME_TO_TIMEVAL(t,tv) \
G_STMT_START { \
g_assert ("Value of time " #t " is out of timeval's range" && \
((t) / GST_SECOND) < G_MAXLONG); \
(tv).tv_sec = (glong) (((GstClockTime) (t)) / GST_SECOND); \
(tv).tv_usec = (glong) ((((GstClockTime) (t)) - \
((GstClockTime) (tv).tv_sec) * GST_SECOND) \
/ GST_USECOND); \
#define GST_TIME_TO_TIMEVAL(t,tv) \
G_STMT_START { \
G_STATIC_ASSERT (sizeof ((tv).tv_sec) == 4 || sizeof ((tv).tv_sec) == 8); \
if (sizeof ((tv).tv_sec) == 4) { \
g_assert ("Value of time " #t " is out of timeval's range" && \
((t) / GST_SECOND) < G_MAXINT32); \
} \
(tv).tv_sec = (((GstClockTime) (t)) / GST_SECOND); \
(tv).tv_usec = ((((GstClockTime) (t)) - \
((GstClockTime) (tv).tv_sec) * GST_SECOND) \
/ GST_USECOND); \
} G_STMT_END
/**
@ -203,12 +207,15 @@ G_STMT_START { \
*
* Converts a #GstClockTime to a struct timespec (see `man pselect`)
*/
#define GST_TIME_TO_TIMESPEC(t,ts) \
G_STMT_START { \
g_assert ("Value of time " #t " is out of timespec's range" && \
((t) / GST_SECOND) < G_MAXLONG); \
(ts).tv_sec = (glong) ((t) / GST_SECOND); \
(ts).tv_nsec = (glong) (((t) - (ts).tv_sec * GST_SECOND) / GST_NSECOND); \
#define GST_TIME_TO_TIMESPEC(t,ts) \
G_STMT_START { \
G_STATIC_ASSERT (sizeof ((ts).tv_sec) == 4 || sizeof ((ts).tv_sec) == 8); \
if (sizeof ((ts).tv_sec) == 4) { \
g_assert ("Value of time " #t " is out of timespec's range" && \
((t) / GST_SECOND) < G_MAXINT32); \
} \
(ts).tv_sec = ((t) / GST_SECOND); \
(ts).tv_nsec = (((t) - (ts).tv_sec * GST_SECOND) / GST_NSECOND); \
} G_STMT_END
/* timestamp debugging macros */