diff options
Diffstat (limited to 'lib/libpthread')
| -rw-r--r-- | lib/libpthread/thread/thr_cancel.c | 19 | ||||
| -rw-r--r-- | lib/libpthread/thread/thr_cond.c | 2 | ||||
| -rw-r--r-- | lib/libpthread/thread/thr_join.c | 1 | ||||
| -rw-r--r-- | lib/libpthread/thread/thr_kern.c | 2 | ||||
| -rw-r--r-- | lib/libpthread/thread/thr_mutex.c | 1 | ||||
| -rw-r--r-- | lib/libpthread/thread/thr_write.c | 4 | 
6 files changed, 21 insertions, 8 deletions
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 */  | 
