mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-08 22:30: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-block \
|
||||||
pt-timedblock \
|
pt-timedblock \
|
||||||
|
pt-block-intr \
|
||||||
|
pt-timedblock-intr \
|
||||||
pt-wakeup \
|
pt-wakeup \
|
||||||
pt-docancel \
|
pt-docancel \
|
||||||
pt-sysdep \
|
pt-sysdep \
|
||||||
|
@ -270,6 +270,14 @@ extern error_t __pthread_timedblock (struct __pthread *__restrict thread,
|
|||||||
const struct timespec *__restrict abstime,
|
const struct timespec *__restrict abstime,
|
||||||
clockid_t clock_id);
|
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. */
|
/* Wakeup THREAD. */
|
||||||
extern void __pthread_wakeup (struct __pthread *thread);
|
extern void __pthread_wakeup (struct __pthread *thread);
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ __sem_timedwait_internal (sem_t *restrict sem,
|
|||||||
error_t err;
|
error_t err;
|
||||||
int drain;
|
int drain;
|
||||||
struct __pthread *self;
|
struct __pthread *self;
|
||||||
|
clockid_t clock_id = CLOCK_REALTIME;
|
||||||
|
|
||||||
__pthread_spin_lock (&sem->__lock);
|
__pthread_spin_lock (&sem->__lock);
|
||||||
if (sem->__value > 0)
|
if (sem->__value > 0)
|
||||||
@ -54,12 +55,9 @@ __sem_timedwait_internal (sem_t *restrict sem,
|
|||||||
|
|
||||||
/* Block the thread. */
|
/* Block the thread. */
|
||||||
if (timeout != NULL)
|
if (timeout != NULL)
|
||||||
err = __pthread_timedblock (self, timeout, CLOCK_REALTIME);
|
err = __pthread_timedblock_intr (self, timeout, clock_id);
|
||||||
else
|
else
|
||||||
{
|
err = __pthread_block_intr (self);
|
||||||
err = 0;
|
|
||||||
__pthread_block (self);
|
|
||||||
}
|
|
||||||
|
|
||||||
__pthread_spin_lock (&sem->__lock);
|
__pthread_spin_lock (&sem->__lock);
|
||||||
if (self->prevp == NULL)
|
if (self->prevp == NULL)
|
||||||
@ -82,7 +80,7 @@ __sem_timedwait_internal (sem_t *restrict sem,
|
|||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
assert (err == ETIMEDOUT);
|
assert (err == ETIMEDOUT || err == EINTR);
|
||||||
errno = err;
|
errno = err;
|
||||||
return -1;
|
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>
|
#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. */
|
/* Block THREAD. */
|
||||||
void
|
RETTYPE
|
||||||
__pthread_block (struct __pthread *thread)
|
__pthread_block (struct __pthread *thread)
|
||||||
{
|
{
|
||||||
mach_msg_header_t msg;
|
mach_msg_header_t msg;
|
||||||
error_t err;
|
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,
|
thread->wakeupmsg.msgh_remote_port,
|
||||||
MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
|
MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
|
||||||
|
if ((MSG_OPTIONS & MACH_RCV_INTERRUPT) && err == MACH_RCV_INTERRUPTED)
|
||||||
|
RETURN(EINTR);
|
||||||
assert_perror (err);
|
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>
|
#include <pt-internal.h>
|
||||||
|
|
||||||
|
#ifndef MSG_OPTIONS
|
||||||
|
# define MSG_OPTIONS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Block THREAD. */
|
/* Block THREAD. */
|
||||||
error_t
|
error_t
|
||||||
__pthread_timedblock (struct __pthread *thread,
|
__pthread_timedblock (struct __pthread *thread,
|
||||||
@ -54,11 +58,13 @@ __pthread_timedblock (struct __pthread *thread,
|
|||||||
/* Need to do a carry. */
|
/* Need to do a carry. */
|
||||||
timeout -= (now.tv_nsec - abstime->tv_nsec + 999999) / 1000000;
|
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,
|
sizeof msg, thread->wakeupmsg.msgh_remote_port,
|
||||||
timeout, MACH_PORT_NULL);
|
timeout, MACH_PORT_NULL);
|
||||||
if (err == EMACH_RCV_TIMED_OUT)
|
if (err == EMACH_RCV_TIMED_OUT)
|
||||||
return ETIMEDOUT;
|
return ETIMEDOUT;
|
||||||
|
if ((MSG_OPTIONS & MACH_RCV_INTERRUPT) && err == MACH_RCV_INTERRUPTED)
|
||||||
|
return EINTR;
|
||||||
|
|
||||||
assert_perror (err);
|
assert_perror (err);
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user