예제 #1
0
static inline void
testcancel(struct pthread *curthread)
{
	if (__predict_false(SHOULD_CANCEL(curthread) &&
	    !THR_IN_CRITICAL(curthread)))
		_pthread_exit(PTHREAD_CANCELED);
}
예제 #2
0
void
_thr_cancel_leave(struct pthread *curthread, int maycancel)
{
	curthread->cancel_point = 0;
	if (__predict_false(SHOULD_CANCEL(curthread) &&
	    !THR_IN_CRITICAL(curthread) && maycancel))
		_pthread_exit(PTHREAD_CANCELED);
}
예제 #3
0
static inline void
testcancel(struct pthread *curthread)
{
	int newval;

	newval = curthread->cancelflags;
	if (SHOULD_CANCEL(newval))
		_pthread_exit(PTHREAD_CANCELED);
}
예제 #4
0
void
_thr_cancel_enter2(struct pthread *curthread, int maycancel)
{
	curthread->cancel_point = 1;
	if (__predict_false(SHOULD_CANCEL(curthread) &&
	    !THR_IN_CRITICAL(curthread))) {
		if (!maycancel)
			thr_wake(curthread->tid);
		else
			_pthread_exit(PTHREAD_CANCELED);
	}
}
예제 #5
0
파일: thr_cond.c 프로젝트: AhmadTux/freebsd
static int
cond_wait_user(struct pthread_cond *cvp, struct pthread_mutex *mp,
	const struct timespec *abstime, int cancel)
{
	struct pthread	*curthread = _get_curthread();
	struct sleepqueue *sq;
	int	recurse;
	int	error;

	if (curthread->wchan != NULL)
		PANIC("thread was already on queue.");

	if (cancel)
		_thr_testcancel(curthread);

	_sleepq_lock(cvp);
	/*
	 * set __has_user_waiters before unlocking mutex, this allows
	 * us to check it without locking in pthread_cond_signal().
	 */
	cvp->__has_user_waiters = 1; 
	curthread->will_sleep = 1;
	(void)_mutex_cv_unlock(mp, &recurse);
	curthread->mutex_obj = mp;
	_sleepq_add(cvp, curthread);
	for(;;) {
		_thr_clear_wake(curthread);
		_sleepq_unlock(cvp);

		if (cancel) {
			_thr_cancel_enter2(curthread, 0);
			error = _thr_sleep(curthread, cvp->__clock_id, abstime);
			_thr_cancel_leave(curthread, 0);
		} else {
			error = _thr_sleep(curthread, cvp->__clock_id, abstime);
		}

		_sleepq_lock(cvp);
		if (curthread->wchan == NULL) {
			error = 0;
			break;
		} else if (cancel && SHOULD_CANCEL(curthread)) {
			sq = _sleepq_lookup(cvp);
			cvp->__has_user_waiters = 
				_sleepq_remove(sq, curthread);
			_sleepq_unlock(cvp);
			curthread->mutex_obj = NULL;
			_mutex_cv_lock(mp, recurse);
			if (!THR_IN_CRITICAL(curthread))
				_pthread_exit(PTHREAD_CANCELED);
			else /* this should not happen */
				return (0);
		} else if (error == ETIMEDOUT) {
			sq = _sleepq_lookup(cvp);
			cvp->__has_user_waiters =
				_sleepq_remove(sq, curthread);
			break;
		}
	}
	_sleepq_unlock(cvp);
	curthread->mutex_obj = NULL;
	_mutex_cv_lock(mp, recurse);
	return (error);
}