Samuel Thibault, le dim. 23 août 2026 11:11:52 +0200, a ecrit:
> Samuel Thibault, le dim. 23 août 2026 10:24:52 +0200, a ecrit:
> > One thing that is a bug, however, is the program below, which stays
> > blocked because the mach_msg calling loop keeps using the same timeout.
> >
> > We probably need a version that takes a clock_id and an absolute time,
> > and does the clock_gettime call itself on each mach_msg calling loop.
>
> Or probably simpler: make __pthread_timedblock always pass
> MACH_RCV_INTERRUPT to __mach_msg, but loop around if it returns EINTR
> and MACH_RCV_INTERRUPT was not in MSG_OPTIONS.
Could you try this?
Samuel
Index: glibc-2.43/sysdeps/mach/htl/pt-timedblock.c
===================================================================
--- glibc-2.43.orig/sysdeps/mach/htl/pt-timedblock.c
+++ glibc-2.43/sysdeps/mach/htl/pt-timedblock.c
@@ -40,6 +40,7 @@ __pthread_timedblock (struct __pthread *
mach_msg_timeout_t timeout;
struct timespec now;
+retry:
/* We have an absolute time and now we have to convert it to a
relative time. Arg. */
@@ -58,13 +59,19 @@ __pthread_timedblock (struct __pthread *
/* Need to do a carry. */
timeout -= (now.tv_nsec - abstime->tv_nsec + 999999) / 1000000;
- err = __mach_msg (&msg, MACH_RCV_MSG | MACH_RCV_TIMEOUT | MSG_OPTIONS, 0,
+ err = __mach_msg (&msg, MACH_RCV_MSG | MACH_RCV_TIMEOUT | MSG_OPTIONS |
MACH_RCV_INTERRUPT, 0,
sizeof msg, thread->wakeupmsg.msgh_remote_port,
timeout, MACH_PORT_NULL);
if (err == EMACH_RCV_TIMED_OUT)
return ETIMEDOUT;
- if ((MSG_OPTIONS & MACH_RCV_INTERRUPT) && err == MACH_RCV_INTERRUPTED)
- return EINTR;
+ if (err == MACH_RCV_INTERRUPTED)
+ {
+ if (!((MSG_OPTIONS & MACH_RCV_INTERRUPT)))
+ /* Re-take absolute time target. */
+ goto retry;
+ else
+ return EINTR;
+ }
assert_perror (err);
return 0;