mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-08 14:20:07 +00:00
htl: Make sem_wait/sem_timedwait interruptible
This commit is contained in:
parent
1cec114b17
commit
e9644c20ce
@ -108,6 +108,8 @@ libpthread-routines := pt-attr pt-attr-destroy pt-attr-getdetachstate \
|
||||
\
|
||||
pt-block \
|
||||
pt-timedblock \
|
||||
pt-block-intr \
|
||||
pt-timedblock-intr \
|
||||
pt-wakeup \
|
||||
pt-docancel \
|
||||
pt-sysdep \
|
||||
|
@ -270,6 +270,14 @@ extern error_t __pthread_timedblock (struct __pthread *__restrict thread,
|
||||
const struct timespec *__restrict abstime,
|
||||
clockid_t clock_id);
|
||||
|
||||
/* Block THREAD with interrupts. */
|
||||
extern error_t __pthread_block_intr (struct __pthread *thread);
|
||||
|
||||
/* Block THREAD until *ABSTIME is reached, with interrupts. */
|
||||
extern error_t __pthread_timedblock_intr (struct __pthread *__restrict thread,
|
||||
const struct timespec *__restrict abstime,
|
||||
clockid_t clock_id);
|
||||
|
||||
/* Wakeup THREAD. */
|
||||
extern void __pthread_wakeup (struct __pthread *thread);
|
||||
|
||||
|
@ -30,6 +30,7 @@ __sem_timedwait_internal (sem_t *restrict sem,
|
||||
error_t err;
|
||||
int drain;
|
||||
struct __pthread *self;
|
||||
clockid_t clock_id = CLOCK_REALTIME;
|
||||
|
||||
__pthread_spin_lock (&sem->__lock);
|
||||
if (sem->__value > 0)
|
||||
@ -54,12 +55,9 @@ __sem_timedwait_internal (sem_t *restrict sem,
|
||||
|
||||
/* Block the thread. */
|
||||
if (timeout != NULL)
|
||||
err = __pthread_timedblock (self, timeout, CLOCK_REALTIME);
|
||||
err = __pthread_timedblock_intr (self, timeout, clock_id);
|
||||
else
|
||||
{
|
||||
err = 0;
|
||||
__pthread_block (self);
|
||||
}
|
||||
err = __pthread_block_intr (self);
|
||||
|
||||
__pthread_spin_lock (&sem->__lock);
|
||||
if (self->prevp == NULL)
|
||||
@ -82,7 +80,7 @@ __sem_timedwait_internal (sem_t *restrict sem,
|
||||
|
||||
if (err)
|
||||
{
|
||||
assert (err == ETIMEDOUT);
|
||||
assert (err == ETIMEDOUT || err == EINTR);
|
||||
errno = err;
|
||||
return -1;
|
||||
}
|
||||
|
6
sysdeps/mach/htl/pt-block-intr.c
Normal file
6
sysdeps/mach/htl/pt-block-intr.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include <pt-internal.h>
|
||||
#define RETTYPE error_t
|
||||
#define RETURN(val) return val
|
||||
#define __pthread_block __pthread_block_intr
|
||||
#define MSG_OPTIONS MACH_RCV_INTERRUPT
|
||||
#include "pt-block.c"
|
@ -24,15 +24,30 @@
|
||||
|
||||
#include <pt-internal.h>
|
||||
|
||||
#ifndef MSG_OPTIONS
|
||||
# define MSG_OPTIONS 0
|
||||
#endif
|
||||
|
||||
#ifndef RETTYPE
|
||||
# define RETTYPE void
|
||||
#endif
|
||||
|
||||
#ifndef RETURN
|
||||
# define RETURN(val)
|
||||
#endif
|
||||
|
||||
/* Block THREAD. */
|
||||
void
|
||||
RETTYPE
|
||||
__pthread_block (struct __pthread *thread)
|
||||
{
|
||||
mach_msg_header_t msg;
|
||||
error_t err;
|
||||
|
||||
err = __mach_msg (&msg, MACH_RCV_MSG, 0, sizeof msg,
|
||||
err = __mach_msg (&msg, MACH_RCV_MSG | MSG_OPTIONS, 0, sizeof msg,
|
||||
thread->wakeupmsg.msgh_remote_port,
|
||||
MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
|
||||
if ((MSG_OPTIONS & MACH_RCV_INTERRUPT) && err == MACH_RCV_INTERRUPTED)
|
||||
RETURN(EINTR);
|
||||
assert_perror (err);
|
||||
RETURN(0);
|
||||
}
|
||||
|
3
sysdeps/mach/htl/pt-timedblock-intr.c
Normal file
3
sysdeps/mach/htl/pt-timedblock-intr.c
Normal file
@ -0,0 +1,3 @@
|
||||
#define __pthread_timedblock __pthread_timedblock_intr
|
||||
#define MSG_OPTIONS MACH_RCV_INTERRUPT
|
||||
#include "pt-timedblock.c"
|
@ -26,6 +26,10 @@
|
||||
|
||||
#include <pt-internal.h>
|
||||
|
||||
#ifndef MSG_OPTIONS
|
||||
# define MSG_OPTIONS 0
|
||||
#endif
|
||||
|
||||
/* Block THREAD. */
|
||||
error_t
|
||||
__pthread_timedblock (struct __pthread *thread,
|
||||
@ -54,11 +58,13 @@ __pthread_timedblock (struct __pthread *thread,
|
||||
/* Need to do a carry. */
|
||||
timeout -= (now.tv_nsec - abstime->tv_nsec + 999999) / 1000000;
|
||||
|
||||
err = __mach_msg (&msg, MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0,
|
||||
err = __mach_msg (&msg, MACH_RCV_MSG | MACH_RCV_TIMEOUT | MSG_OPTIONS, 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;
|
||||
|
||||
assert_perror (err);
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user