mirror of
https://sourceware.org/git/glibc.git
synced 2025-12-24 17:51:17 +03:00
Update.
* sysdeps/alpha/dl-machine.h (RTLD_START):Rewrite for new init function interface. Patch by Richard Henderson <rth@cygnus.com>.
This commit is contained in:
@@ -195,10 +195,6 @@ int sem_timedwait(sem_t *sem, const struct timespec *abstime)
|
||||
pthread_descr self = thread_self();
|
||||
pthread_extricate_if extr;
|
||||
int already_canceled = 0;
|
||||
int was_signalled = 0;
|
||||
sigjmp_buf jmpbuf;
|
||||
sigset_t unblock;
|
||||
sigset_t initial_mask;
|
||||
|
||||
__pthread_lock((pthread_spinlock_t *) &sem->__sem_lock, self);
|
||||
if (sem->__sem_value > 0) {
|
||||
@@ -233,56 +229,7 @@ int sem_timedwait(sem_t *sem, const struct timespec *abstime)
|
||||
pthread_exit(PTHREAD_CANCELED);
|
||||
}
|
||||
|
||||
/* Set up a longjmp handler for the restart signal, unblock
|
||||
the signal and sleep. */
|
||||
|
||||
if (sigsetjmp(jmpbuf, 1) == 0) {
|
||||
THREAD_SETMEM(self, p_signal_jmp, &jmpbuf);
|
||||
THREAD_SETMEM(self, p_signal, 0);
|
||||
/* Unblock the restart signal */
|
||||
sigemptyset(&unblock);
|
||||
sigaddset(&unblock, __pthread_sig_restart);
|
||||
sigprocmask(SIG_UNBLOCK, &unblock, &initial_mask);
|
||||
|
||||
while (1) {
|
||||
struct timeval now;
|
||||
struct timespec reltime;
|
||||
|
||||
/* Compute a time offset relative to now. */
|
||||
__gettimeofday (&now, NULL);
|
||||
reltime.tv_nsec = abstime->tv_nsec - now.tv_usec * 1000;
|
||||
reltime.tv_sec = abstime->tv_sec - now.tv_sec;
|
||||
if (reltime.tv_nsec < 0) {
|
||||
reltime.tv_nsec += 1000000000;
|
||||
reltime.tv_sec -= 1;
|
||||
}
|
||||
|
||||
/* Sleep for the required duration. If woken by a signal,
|
||||
resume waiting as required by Single Unix Specification. */
|
||||
if (reltime.tv_sec < 0 || __libc_nanosleep(&reltime, NULL) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Block the restart signal again */
|
||||
sigprocmask(SIG_SETMASK, &initial_mask, NULL);
|
||||
was_signalled = 0;
|
||||
} else {
|
||||
was_signalled = 1;
|
||||
}
|
||||
THREAD_SETMEM(self, p_signal_jmp, NULL);
|
||||
|
||||
/* Now was_signalled is true if we exited the above code
|
||||
due to the delivery of a restart signal. In that case,
|
||||
everything is cool. We have been removed from the queue
|
||||
by the other thread, and consumed its signal.
|
||||
|
||||
Otherwise we this thread woke up spontaneously, or due to a signal other
|
||||
than restart. The next thing to do is to try to remove the thread
|
||||
from the queue. This may fail due to a race against another thread
|
||||
trying to do the same. In the failed case, we know we were signalled,
|
||||
and we may also have to consume a restart signal. */
|
||||
|
||||
if (!was_signalled) {
|
||||
if (timedsuspend(self, abstime) == 0) {
|
||||
int was_on_queue;
|
||||
|
||||
/* __pthread_lock will queue back any spurious restarts that
|
||||
|
||||
Reference in New Issue
Block a user