winpthreads: mutex.c: improve `pthread_mutex_timedlock` POSIX[1] does not specify behavior when the second argument to `pthread_mutex_timedlock` is NULL; assume it is always non-NULL. Follow POSIX[1] specification and fail with EINVAL if `tv_nsec` field of passed `struct timespec` is less than zero or greater than or equal to 1000000000. Replace uses of `unsigned long long` with more MSVC-friendly `unsigned __int64`. Cast `patience` variable to `DWORD` when calling `pthread_mutex_lock_intern`; this avoids MSVC warning C4244. [1] https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/pthread_mutex_clocklock.html Signed-off-by: Kirill Makurin <maiddaisuki@outlook.com> Signed-off-by: LIU Hao <lh_mouse@126.com>
diff --git a/mingw-w64-libraries/winpthreads/src/mutex.c b/mingw-w64-libraries/winpthreads/src/mutex.c index 77f045b..d27c1e2 100644 --- a/mingw-w64-libraries/winpthreads/src/mutex.c +++ b/mingw-w64-libraries/winpthreads/src/mutex.c
@@ -234,17 +234,27 @@ int pthread_mutex_timedlock64(pthread_mutex_t *m, const struct _timespec64 *ts) { - unsigned long long patience; - if (ts != NULL) { - unsigned long long end = _pthread_time_in_ms_from_timespec(ts); - unsigned long long now = _pthread_time_in_ms(); - patience = end > now ? end - now : 0; - if (patience > 0xffffffff) - patience = INFINITE; - } else { + /** + * The pthread_mutex_timedlock() function shall fail if: + * + * [EINVAL] + * The process or thread would have blocked, and the abstime parameter + * specified a nanoseconds field value less than zero or greater than + * or equal to 1000 million. + */ + if (ts->tv_nsec < 0 || ts->tv_nsec >= 1000000000) { + return EINVAL; + } + + unsigned __int64 end = _pthread_time_in_ms_from_timespec (ts); + unsigned __int64 now = _pthread_time_in_ms (); + unsigned __int64 patience = end > now ? end - now : 0; + + if (patience > 0xffffffff) { patience = INFINITE; } - return pthread_mutex_lock_intern(m, patience); + + return pthread_mutex_lock_intern(m, (DWORD) patience); } int pthread_mutex_timedlock32(pthread_mutex_t *m, const struct _timespec32 *ts)