From 8456ca731197cd424e1d5a70363f568d2424d38b Mon Sep 17 00:00:00 2001 From: deischen Date: Fri, 17 Dec 1999 00:57:54 +0000 Subject: [PATCH] Fix problems with cancellation while in critical regions. o Cancellation flags were not getting properly set/cleared. o Loops waiting for internal locks were not being exited correctly by a cancelled thread. o Minor spelling (cancelation -> cancellation) and formatting corrections (missing tab). Found by: tg Reviewed by: jasone --- lib/libc_r/uthread/uthread_cancel.c | 19 ++++++++---- lib/libc_r/uthread/uthread_cond.c | 2 ++ lib/libc_r/uthread/uthread_fd.c | 45 +++++++++++++++++++---------- lib/libc_r/uthread/uthread_file.c | 3 +- lib/libc_r/uthread/uthread_join.c | 1 + lib/libc_r/uthread/uthread_kern.c | 2 +- lib/libc_r/uthread/uthread_mutex.c | 1 + lib/libc_r/uthread/uthread_write.c | 4 +-- lib/libkse/thread/thr_cancel.c | 19 ++++++++---- lib/libkse/thread/thr_cond.c | 2 ++ lib/libkse/thread/thr_join.c | 1 + lib/libkse/thread/thr_kern.c | 2 +- lib/libkse/thread/thr_mutex.c | 1 + lib/libkse/thread/thr_write.c | 4 +-- lib/libpthread/thread/thr_cancel.c | 19 ++++++++---- lib/libpthread/thread/thr_cond.c | 2 ++ lib/libpthread/thread/thr_join.c | 1 + lib/libpthread/thread/thr_kern.c | 2 +- lib/libpthread/thread/thr_mutex.c | 1 + lib/libpthread/thread/thr_write.c | 4 +-- 20 files changed, 95 insertions(+), 40 deletions(-) diff --git a/lib/libc_r/uthread/uthread_cancel.c b/lib/libc_r/uthread/uthread_cancel.c index bad55339d067..de7c491ca960 100644 --- a/lib/libc_r/uthread/uthread_cancel.c +++ b/lib/libc_r/uthread/uthread_cancel.c @@ -20,8 +20,16 @@ pthread_cancel(pthread_t pthread) /* Protect the scheduling queues: */ _thread_kern_sig_defer(); - /* Check if we need to kick it back into the run queue: */ - if ((pthread->cancelflags & PTHREAD_CANCEL_DISABLE) == 0) + if (((pthread->cancelflags & PTHREAD_CANCEL_DISABLE) != 0) || + (((pthread->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) == 0) && + ((pthread->cancelflags & PTHREAD_AT_CANCEL_POINT) == 0))) + /* Just mark it for cancellation: */ + pthread->cancelflags |= PTHREAD_CANCELLING; + else { + /* + * Check if we need to kick it back into the + * run queue: + */ switch (pthread->state) { case PS_RUNNING: /* No need to resume: */ @@ -33,7 +41,7 @@ pthread_cancel(pthread_t pthread) case PS_FDW_WAIT: case PS_POLL_WAIT: case PS_SELECT_WAIT: - /* Remove these threads from the work queue: */ + /* Remove these threads from the work queue: */ if ((pthread->flags & PTHREAD_FLAGS_IN_WORKQ) != 0) PTHREAD_WORKQ_REMOVE(pthread); @@ -75,7 +83,9 @@ pthread_cancel(pthread_t pthread) case PS_STATE_MAX: /* Ignore - only here to silence -Wall: */ break; + } } + /* Unprotect the scheduling queues: */ _thread_kern_sig_undefer(); @@ -96,7 +106,7 @@ pthread_setcancelstate(int state, int *oldstate) case PTHREAD_CANCEL_ENABLE: if (oldstate != NULL) *oldstate = ostate; - _thread_run->cancelflags &= PTHREAD_CANCEL_ENABLE; + _thread_run->cancelflags &= ~PTHREAD_CANCEL_DISABLE; if ((_thread_run->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) != 0) pthread_testcancel(); ret = 0; @@ -145,7 +155,6 @@ pthread_setcanceltype(int type, int *oldtype) void pthread_testcancel(void) { - if (((_thread_run->cancelflags & PTHREAD_CANCEL_DISABLE) == 0) && ((_thread_run->cancelflags & PTHREAD_CANCELLING) != 0)) { /* diff --git a/lib/libc_r/uthread/uthread_cond.c b/lib/libc_r/uthread/uthread_cond.c index 09c5f22d0523..3e215af2ed60 100644 --- a/lib/libc_r/uthread/uthread_cond.c +++ b/lib/libc_r/uthread/uthread_cond.c @@ -274,6 +274,7 @@ pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex) } if ((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) { + _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED; _thread_exit_cleanup(); pthread_exit(PTHREAD_CANCELED); } @@ -431,6 +432,7 @@ pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex, } if ((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) { + _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED; _thread_exit_cleanup(); pthread_exit(PTHREAD_CANCELED); } diff --git a/lib/libc_r/uthread/uthread_fd.c b/lib/libc_r/uthread/uthread_fd.c index 3b696396fc69..d9a16360c754 100644 --- a/lib/libc_r/uthread/uthread_fd.c +++ b/lib/libc_r/uthread/uthread_fd.c @@ -398,12 +398,13 @@ _thread_fd_lock(int fd, int lock_type, struct timespec * timeout) } /* Check the file descriptor and lock types: */ - if (lock_type == FD_WRITE || lock_type == FD_RDWR) { + if (_thread_run->interrupted == 0 && + (lock_type == FD_WRITE || lock_type == FD_RDWR)) { /* - * Enter a loop to wait for the file descriptor to be - * locked for write for the current thread: + * Wait for the file descriptor to be locked + * for write for the current thread: */ - while (_thread_fd_table[fd]->w_owner != _thread_run) { + if (_thread_fd_table[fd]->w_owner != _thread_run) { /* * Check if the file descriptor is locked by * another thread: @@ -483,6 +484,7 @@ _thread_fd_lock(int fd, int lock_type, struct timespec * timeout) ret = -1; errno = EINTR; } else { + _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED; _thread_exit_cleanup(); pthread_exit(PTHREAD_CANCELED); } @@ -639,10 +641,10 @@ _thread_fd_lock_debug(int fd, int lock_type, struct timespec * timeout, /* Check the file descriptor and lock types: */ if (lock_type == FD_READ || lock_type == FD_RDWR) { /* - * Enter a loop to wait for the file descriptor to be - * locked for read for the current thread: + * Wait for the file descriptor to be locked + * for read for the current thread: */ - while (_thread_fd_table[fd]->r_owner != _thread_run) { + if (_thread_fd_table[fd]->r_owner != _thread_run) { /* * Check if the file descriptor is locked by * another thread: @@ -691,6 +693,10 @@ _thread_fd_lock_debug(int fd, int lock_type, struct timespec * timeout, */ _SPINLOCK(&_thread_fd_table[fd]->lock); + if (_thread_run->interrupted != 0) { + FDQ_REMOVE(&_thread_fd_table[fd]->r_queue, + _thread_run); + } } else { /* * The running thread now owns the @@ -713,17 +719,19 @@ _thread_fd_lock_debug(int fd, int lock_type, struct timespec * timeout, } } - /* Increment the read lock count: */ - _thread_fd_table[fd]->r_lockcount++; + if (_thread_fd_table[fd]->r_owner == _thread_run) + /* Increment the read lock count: */ + _thread_fd_table[fd]->r_lockcount++; } /* Check the file descriptor and lock types: */ - if (lock_type == FD_WRITE || lock_type == FD_RDWR) { + if (_thread_run->interrupted == 0 && + (lock_type == FD_WRITE || lock_type == FD_RDWR)) { /* - * Enter a loop to wait for the file descriptor to be - * locked for write for the current thread: + * Wait for the file descriptor to be locked + * for write for the current thread: */ - while (_thread_fd_table[fd]->w_owner != _thread_run) { + if (_thread_fd_table[fd]->w_owner != _thread_run) { /* * Check if the file descriptor is locked by * another thread: @@ -771,6 +779,11 @@ _thread_fd_lock_debug(int fd, int lock_type, struct timespec * timeout, * table entry again: */ _SPINLOCK(&_thread_fd_table[fd]->lock); + + if (_thread_run->interrupted != 0) { + FDQ_REMOVE(&_thread_fd_table[fd]->w_queue, + _thread_run); + } } else { /* * The running thread now owns the @@ -794,8 +807,9 @@ _thread_fd_lock_debug(int fd, int lock_type, struct timespec * timeout, } } - /* Increment the write lock count: */ - _thread_fd_table[fd]->w_lockcount++; + if (_thread_fd_table[fd]->w_owner == _thread_run) + /* Increment the write lock count: */ + _thread_fd_table[fd]->w_lockcount++; } /* Unlock the file descriptor table entry: */ @@ -806,6 +820,7 @@ _thread_fd_lock_debug(int fd, int lock_type, struct timespec * timeout, ret = -1; errno = EINTR; } else { + _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED; _thread_exit_cleanup(); pthread_exit(PTHREAD_CANCELED); } diff --git a/lib/libc_r/uthread/uthread_file.c b/lib/libc_r/uthread/uthread_file.c index 5c89b09cfc92..f1bac17af195 100644 --- a/lib/libc_r/uthread/uthread_file.c +++ b/lib/libc_r/uthread/uthread_file.c @@ -256,7 +256,8 @@ _flockfile_debug(FILE * fp, char *fname, int lineno) _thread_kern_sig_undefer(); if (((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) && - (_thread_run->cancelflags & PTHREAD_CANCEL_DISABLE) != 0) { + (_thread_run->cancelflags & PTHREAD_CANCEL_DISABLE) != 0) { + _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED; _thread_exit_cleanup(); pthread_exit(PTHREAD_CANCELED); } diff --git a/lib/libc_r/uthread/uthread_join.c b/lib/libc_r/uthread/uthread_join.c index d149cf16e303..155dc6435e83 100644 --- a/lib/libc_r/uthread/uthread_join.c +++ b/lib/libc_r/uthread/uthread_join.c @@ -98,6 +98,7 @@ pthread_join(pthread_t pthread, void **thread_return) _thread_kern_sig_undefer(); if ((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) { + _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED; _thread_exit_cleanup(); pthread_exit(PTHREAD_CANCELED); } diff --git a/lib/libc_r/uthread/uthread_kern.c b/lib/libc_r/uthread/uthread_kern.c index f69cb41f4f2d..b3fbc3ac3434 100644 --- a/lib/libc_r/uthread/uthread_kern.c +++ b/lib/libc_r/uthread/uthread_kern.c @@ -111,7 +111,7 @@ __asm__("fnsave %0": :"m"(*fdata)); if (((_thread_run->cancelflags & PTHREAD_AT_CANCEL_POINT) == 0) && ((_thread_run->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) != 0)) { /* - * Cancelations override signals. + * Cancellations override signals. * * Stick a cancellation point at the start of * each async-cancellable thread's resumption. diff --git a/lib/libc_r/uthread/uthread_mutex.c b/lib/libc_r/uthread/uthread_mutex.c index b2a06f2fc2e5..c625ef26e900 100644 --- a/lib/libc_r/uthread/uthread_mutex.c +++ b/lib/libc_r/uthread/uthread_mutex.c @@ -623,6 +623,7 @@ pthread_mutex_lock(pthread_mutex_t * mutex) _thread_kern_sig_undefer(); if ((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) { + _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED; _thread_exit_cleanup(); pthread_exit(PTHREAD_CANCELED); } diff --git a/lib/libc_r/uthread/uthread_write.c b/lib/libc_r/uthread/uthread_write.c index 09b09cdcfdcf..40c4cc574241 100644 --- a/lib/libc_r/uthread/uthread_write.c +++ b/lib/libc_r/uthread/uthread_write.c @@ -67,8 +67,8 @@ write(int fd, const void *buf, size_t nbytes) /* File is not open for write: */ errno = EBADF; _FD_UNLOCK(fd, FD_WRITE); - _thread_leave_cancellation_point(); - return (-1); + _thread_leave_cancellation_point(); + return (-1); } /* Check if file operations are to block */ diff --git a/lib/libkse/thread/thr_cancel.c b/lib/libkse/thread/thr_cancel.c index bad55339d067..de7c491ca960 100644 --- a/lib/libkse/thread/thr_cancel.c +++ b/lib/libkse/thread/thr_cancel.c @@ -20,8 +20,16 @@ pthread_cancel(pthread_t pthread) /* Protect the scheduling queues: */ _thread_kern_sig_defer(); - /* Check if we need to kick it back into the run queue: */ - if ((pthread->cancelflags & PTHREAD_CANCEL_DISABLE) == 0) + if (((pthread->cancelflags & PTHREAD_CANCEL_DISABLE) != 0) || + (((pthread->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) == 0) && + ((pthread->cancelflags & PTHREAD_AT_CANCEL_POINT) == 0))) + /* Just mark it for cancellation: */ + pthread->cancelflags |= PTHREAD_CANCELLING; + else { + /* + * Check if we need to kick it back into the + * run queue: + */ switch (pthread->state) { case PS_RUNNING: /* No need to resume: */ @@ -33,7 +41,7 @@ pthread_cancel(pthread_t pthread) case PS_FDW_WAIT: case PS_POLL_WAIT: case PS_SELECT_WAIT: - /* Remove these threads from the work queue: */ + /* Remove these threads from the work queue: */ if ((pthread->flags & PTHREAD_FLAGS_IN_WORKQ) != 0) PTHREAD_WORKQ_REMOVE(pthread); @@ -75,7 +83,9 @@ pthread_cancel(pthread_t pthread) case PS_STATE_MAX: /* Ignore - only here to silence -Wall: */ break; + } } + /* Unprotect the scheduling queues: */ _thread_kern_sig_undefer(); @@ -96,7 +106,7 @@ pthread_setcancelstate(int state, int *oldstate) case PTHREAD_CANCEL_ENABLE: if (oldstate != NULL) *oldstate = ostate; - _thread_run->cancelflags &= PTHREAD_CANCEL_ENABLE; + _thread_run->cancelflags &= ~PTHREAD_CANCEL_DISABLE; if ((_thread_run->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) != 0) pthread_testcancel(); ret = 0; @@ -145,7 +155,6 @@ pthread_setcanceltype(int type, int *oldtype) void pthread_testcancel(void) { - if (((_thread_run->cancelflags & PTHREAD_CANCEL_DISABLE) == 0) && ((_thread_run->cancelflags & PTHREAD_CANCELLING) != 0)) { /* diff --git a/lib/libkse/thread/thr_cond.c b/lib/libkse/thread/thr_cond.c index 09c5f22d0523..3e215af2ed60 100644 --- a/lib/libkse/thread/thr_cond.c +++ b/lib/libkse/thread/thr_cond.c @@ -274,6 +274,7 @@ pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex) } if ((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) { + _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED; _thread_exit_cleanup(); pthread_exit(PTHREAD_CANCELED); } @@ -431,6 +432,7 @@ pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex, } if ((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) { + _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED; _thread_exit_cleanup(); pthread_exit(PTHREAD_CANCELED); } diff --git a/lib/libkse/thread/thr_join.c b/lib/libkse/thread/thr_join.c index d149cf16e303..155dc6435e83 100644 --- a/lib/libkse/thread/thr_join.c +++ b/lib/libkse/thread/thr_join.c @@ -98,6 +98,7 @@ pthread_join(pthread_t pthread, void **thread_return) _thread_kern_sig_undefer(); if ((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) { + _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED; _thread_exit_cleanup(); pthread_exit(PTHREAD_CANCELED); } diff --git a/lib/libkse/thread/thr_kern.c b/lib/libkse/thread/thr_kern.c index f69cb41f4f2d..b3fbc3ac3434 100644 --- a/lib/libkse/thread/thr_kern.c +++ b/lib/libkse/thread/thr_kern.c @@ -111,7 +111,7 @@ __asm__("fnsave %0": :"m"(*fdata)); if (((_thread_run->cancelflags & PTHREAD_AT_CANCEL_POINT) == 0) && ((_thread_run->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) != 0)) { /* - * Cancelations override signals. + * Cancellations override signals. * * Stick a cancellation point at the start of * each async-cancellable thread's resumption. diff --git a/lib/libkse/thread/thr_mutex.c b/lib/libkse/thread/thr_mutex.c index b2a06f2fc2e5..c625ef26e900 100644 --- a/lib/libkse/thread/thr_mutex.c +++ b/lib/libkse/thread/thr_mutex.c @@ -623,6 +623,7 @@ pthread_mutex_lock(pthread_mutex_t * mutex) _thread_kern_sig_undefer(); if ((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) { + _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED; _thread_exit_cleanup(); pthread_exit(PTHREAD_CANCELED); } diff --git a/lib/libkse/thread/thr_write.c b/lib/libkse/thread/thr_write.c index 09b09cdcfdcf..40c4cc574241 100644 --- a/lib/libkse/thread/thr_write.c +++ b/lib/libkse/thread/thr_write.c @@ -67,8 +67,8 @@ write(int fd, const void *buf, size_t nbytes) /* File is not open for write: */ errno = EBADF; _FD_UNLOCK(fd, FD_WRITE); - _thread_leave_cancellation_point(); - return (-1); + _thread_leave_cancellation_point(); + return (-1); } /* Check if file operations are to block */ diff --git a/lib/libpthread/thread/thr_cancel.c b/lib/libpthread/thread/thr_cancel.c index bad55339d067..de7c491ca960 100644 --- a/lib/libpthread/thread/thr_cancel.c +++ b/lib/libpthread/thread/thr_cancel.c @@ -20,8 +20,16 @@ pthread_cancel(pthread_t pthread) /* Protect the scheduling queues: */ _thread_kern_sig_defer(); - /* Check if we need to kick it back into the run queue: */ - if ((pthread->cancelflags & PTHREAD_CANCEL_DISABLE) == 0) + if (((pthread->cancelflags & PTHREAD_CANCEL_DISABLE) != 0) || + (((pthread->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) == 0) && + ((pthread->cancelflags & PTHREAD_AT_CANCEL_POINT) == 0))) + /* Just mark it for cancellation: */ + pthread->cancelflags |= PTHREAD_CANCELLING; + else { + /* + * Check if we need to kick it back into the + * run queue: + */ switch (pthread->state) { case PS_RUNNING: /* No need to resume: */ @@ -33,7 +41,7 @@ pthread_cancel(pthread_t pthread) case PS_FDW_WAIT: case PS_POLL_WAIT: case PS_SELECT_WAIT: - /* Remove these threads from the work queue: */ + /* Remove these threads from the work queue: */ if ((pthread->flags & PTHREAD_FLAGS_IN_WORKQ) != 0) PTHREAD_WORKQ_REMOVE(pthread); @@ -75,7 +83,9 @@ pthread_cancel(pthread_t pthread) case PS_STATE_MAX: /* Ignore - only here to silence -Wall: */ break; + } } + /* Unprotect the scheduling queues: */ _thread_kern_sig_undefer(); @@ -96,7 +106,7 @@ pthread_setcancelstate(int state, int *oldstate) case PTHREAD_CANCEL_ENABLE: if (oldstate != NULL) *oldstate = ostate; - _thread_run->cancelflags &= PTHREAD_CANCEL_ENABLE; + _thread_run->cancelflags &= ~PTHREAD_CANCEL_DISABLE; if ((_thread_run->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) != 0) pthread_testcancel(); ret = 0; @@ -145,7 +155,6 @@ pthread_setcanceltype(int type, int *oldtype) void pthread_testcancel(void) { - if (((_thread_run->cancelflags & PTHREAD_CANCEL_DISABLE) == 0) && ((_thread_run->cancelflags & PTHREAD_CANCELLING) != 0)) { /* diff --git a/lib/libpthread/thread/thr_cond.c b/lib/libpthread/thread/thr_cond.c index 09c5f22d0523..3e215af2ed60 100644 --- a/lib/libpthread/thread/thr_cond.c +++ b/lib/libpthread/thread/thr_cond.c @@ -274,6 +274,7 @@ pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex) } if ((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) { + _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED; _thread_exit_cleanup(); pthread_exit(PTHREAD_CANCELED); } @@ -431,6 +432,7 @@ pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex, } if ((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) { + _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED; _thread_exit_cleanup(); pthread_exit(PTHREAD_CANCELED); } diff --git a/lib/libpthread/thread/thr_join.c b/lib/libpthread/thread/thr_join.c index d149cf16e303..155dc6435e83 100644 --- a/lib/libpthread/thread/thr_join.c +++ b/lib/libpthread/thread/thr_join.c @@ -98,6 +98,7 @@ pthread_join(pthread_t pthread, void **thread_return) _thread_kern_sig_undefer(); if ((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) { + _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED; _thread_exit_cleanup(); pthread_exit(PTHREAD_CANCELED); } diff --git a/lib/libpthread/thread/thr_kern.c b/lib/libpthread/thread/thr_kern.c index f69cb41f4f2d..b3fbc3ac3434 100644 --- a/lib/libpthread/thread/thr_kern.c +++ b/lib/libpthread/thread/thr_kern.c @@ -111,7 +111,7 @@ __asm__("fnsave %0": :"m"(*fdata)); if (((_thread_run->cancelflags & PTHREAD_AT_CANCEL_POINT) == 0) && ((_thread_run->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS) != 0)) { /* - * Cancelations override signals. + * Cancellations override signals. * * Stick a cancellation point at the start of * each async-cancellable thread's resumption. diff --git a/lib/libpthread/thread/thr_mutex.c b/lib/libpthread/thread/thr_mutex.c index b2a06f2fc2e5..c625ef26e900 100644 --- a/lib/libpthread/thread/thr_mutex.c +++ b/lib/libpthread/thread/thr_mutex.c @@ -623,6 +623,7 @@ pthread_mutex_lock(pthread_mutex_t * mutex) _thread_kern_sig_undefer(); if ((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) { + _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED; _thread_exit_cleanup(); pthread_exit(PTHREAD_CANCELED); } diff --git a/lib/libpthread/thread/thr_write.c b/lib/libpthread/thread/thr_write.c index 09b09cdcfdcf..40c4cc574241 100644 --- a/lib/libpthread/thread/thr_write.c +++ b/lib/libpthread/thread/thr_write.c @@ -67,8 +67,8 @@ write(int fd, const void *buf, size_t nbytes) /* File is not open for write: */ errno = EBADF; _FD_UNLOCK(fd, FD_WRITE); - _thread_leave_cancellation_point(); - return (-1); + _thread_leave_cancellation_point(); + return (-1); } /* Check if file operations are to block */