PERFORCE change 65508 for review

David Xu davidxu at FreeBSD.org
Fri Nov 19 20:15:31 PST 2004


http://perforce.freebsd.org/chv.cgi?CH=65508

Change 65508 by davidxu at davidxu_alona on 2004/11/20 04:15:10

	1. If thread is exiting, don't return true in checkcancel().
	2. Use thread lock.

Affected files ...

.. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_cancel.c#2 edit

Differences ...

==== //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_cancel.c#2 (text+ko) ====

@@ -14,15 +14,24 @@
 static inline int
 checkcancel(struct pthread *curthread)
 {
-	if (((curthread->cancelflags & PTHREAD_CANCEL_DISABLE) == 0) &&
-	    ((curthread->cancelflags & THR_CANCELLING) != 0)) {
+	if ((curthread->cancelflags & THR_CANCELLING) != 0) {
 		/*
 		 * It is possible for this thread to be swapped out
 		 * while performing cancellation; do not allow it
 		 * to be cancelled again.
 		 */
-		curthread->cancelflags &= ~THR_CANCELLING;
-		return (1);
+		if ((curthread->flags & THR_FLAGS_EXITING) != 0) {
+			/*
+			 * this may happen once, but after this, it
+			 * shouldn't happen again.
+			 */
+			curthread->cancelflags &= ~THR_CANCELLING;
+			return (0);
+		}
+		if ((curthread->cancelflags & PTHREAD_CANCEL_DISABLE) == 0) {
+			curthread->cancelflags &= ~THR_CANCELLING;
+			return (1);
+		}
 	}
 	else
 		return (0);
@@ -33,7 +42,7 @@
 {
 	if (checkcancel(curthread) != 0) {
 		/* Unlock before exiting: */
-		THR_THREAD_UNLOCK(curthread, curthread);
+		THR_UNLOCK(curthread);
 
 		_thr_exit_cleanup();
 		pthread_exit(PTHREAD_CANCELED);
@@ -46,7 +55,7 @@
 {
 	struct pthread *curthread = _get_curthread();
 	struct pthread *joinee = NULL;
-	struct kse_mailbox *kmbx = NULL;
+	long tid = -1;
 	int ret;
 
 	if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/0)) == 0) {
@@ -54,9 +63,7 @@
 		 * Take the thread's lock while we change the cancel flags.
 		 */
 		THR_THREAD_LOCK(curthread, pthread);
-		THR_SCHED_LOCK(curthread, pthread);
 		if (pthread->flags & THR_FLAGS_EXITING) {
-			THR_SCHED_UNLOCK(curthread, pthread);
 			THR_THREAD_UNLOCK(curthread, pthread);
 			_thr_ref_delete(curthread, pthread);
 			return (ESRCH);
@@ -75,40 +82,15 @@
 			case PS_RUNNING:
 				/* No need to resume: */
 				pthread->cancelflags |= THR_CANCELLING;
+				tid = pthread->tid;
 				break;
 
-			case PS_LOCKWAIT:
-				/*
-				 * These can't be removed from the queue.
-				 * Just mark it as cancelling and tell it
-				 * to yield once it leaves the critical
-				 * region.
-				 */
-				pthread->cancelflags |= THR_CANCELLING;
-				pthread->critical_yield = 1;
-				break;
-
-			case PS_SLEEP_WAIT:
-			case PS_SIGSUSPEND:
-			case PS_SIGWAIT:
-				/* Interrupt and resume: */
-				pthread->interrupted = 1;
-				pthread->cancelflags |= THR_CANCELLING;
-				kmbx = _thr_setrunnable_unlocked(pthread);
-				break;
-
 			case PS_JOIN:
 				/* Disconnect the thread from the joinee: */
 				joinee = pthread->join_status.thread;
 				pthread->join_status.thread = NULL;
 				pthread->cancelflags |= THR_CANCELLING;
-				kmbx = _thr_setrunnable_unlocked(pthread);
-				if ((joinee != NULL) &&
-				    (pthread->kseg == joinee->kseg)) {
-					/* Remove the joiner from the joinee. */
-					joinee->joiner = NULL;
-					joinee = NULL;
-				}
+				tid = _thr_setrunnable_unlocked(pthread);
 				break;
 
 			case PS_SUSPENDED:
@@ -126,7 +108,7 @@
 				 */
 				pthread->interrupted = 1;
 				pthread->cancelflags |= THR_CANCEL_NEEDED;
-				kmbx = _thr_setrunnable_unlocked(pthread);
+				tid = _thr_setrunnable_unlocked(pthread);
 				pthread->continuation =
 					_thr_finish_cancellation;
 				break;
@@ -137,29 +119,27 @@
 				/* Ignore - only here to silence -Wall: */
 				break;
 			}
-			if ((pthread->cancelflags & THR_AT_CANCEL_POINT) &&
-			    (pthread->blocked != 0 ||
-			     pthread->attr.flags & PTHREAD_SCOPE_SYSTEM))
-				kse_thr_interrupt(&pthread->tcb->tcb_tmbx,
-					KSE_INTR_INTERRUPT, 0);
+
+#if 0
+			thr_interrupt(pthread->tid, 1);
+#endif
 		}
 
 		/*
 		 * Release the thread's lock and remove the
 		 * reference:
 		 */
-		THR_SCHED_UNLOCK(curthread, pthread);
 		THR_THREAD_UNLOCK(curthread, pthread);
 		_thr_ref_delete(curthread, pthread);
-		if (kmbx != NULL)
-			kse_wakeup(kmbx);
+		if (tid != -1)
+			thr_wake(tid);
 
 		if ((joinee != NULL) &&
 		    (_thr_ref_add(curthread, joinee, /* include dead */1) == 0)) {
 			/* Remove the joiner from the joinee. */
-			THR_SCHED_LOCK(curthread, joinee);
+			THR_THREAD_LOCK(curthread, joinee);
 			joinee->joiner = NULL;
-			THR_SCHED_UNLOCK(curthread, joinee);
+			THR_THREAD_UNLOCK(curthread, joinee);
 			_thr_ref_delete(curthread, joinee);
 		}
 	}
@@ -175,7 +155,7 @@
 	int need_exit = 0;
 
 	/* Take the thread's lock while fiddling with the state: */
-	THR_THREAD_LOCK(curthread, curthread);
+	THR_LOCK(curthread);
 
 	ostate = curthread->cancelflags & PTHREAD_CANCEL_DISABLE;
 
@@ -194,7 +174,7 @@
 		ret = EINVAL;
 	}
 
-	THR_THREAD_UNLOCK(curthread, curthread);
+	THR_UNLOCK(curthread);
 	if (need_exit != 0) {
 		_thr_exit_cleanup();
 		pthread_exit(PTHREAD_CANCELED);
@@ -215,7 +195,7 @@
 	int need_exit = 0;
 
 	/* Take the thread's lock while fiddling with the state: */
-	THR_THREAD_LOCK(curthread, curthread);
+	THR_LOCK(curthread);
 
 	otype = curthread->cancelflags & PTHREAD_CANCEL_ASYNCHRONOUS;
 	switch (type) {
@@ -232,7 +212,7 @@
 		ret = EINVAL;
 	}
 
-	THR_THREAD_UNLOCK(curthread, curthread);
+	THR_UNLOCK(curthread);
 	if (need_exit != 0) {
 		_thr_exit_cleanup();
 		pthread_exit(PTHREAD_CANCELED);
@@ -249,30 +229,30 @@
 {
 	struct pthread	*curthread = _get_curthread();
 
-	THR_THREAD_LOCK(curthread, curthread);
+	THR_LOCK(curthread);
 	testcancel(curthread);
-	THR_THREAD_UNLOCK(curthread, curthread);
+	THR_UNLOCK(curthread);
 }
 
 void
-_thr_cancel_enter(struct pthread *thread)
+_thr_cancel_enter(struct pthread *curthread)
 {
 	/* Look for a cancellation before we block: */
-	THR_THREAD_LOCK(thread, thread);
-	testcancel(thread);
-	thread->cancelflags |= THR_AT_CANCEL_POINT;
-	THR_THREAD_UNLOCK(thread, thread);
+	THR_LOCK(curthread);
+	testcancel(curthread);
+	curthread->cancelflags |= THR_AT_CANCEL_POINT;
+	THR_UNLOCK(curthread);
 }
 
 void
-_thr_cancel_leave(struct pthread *thread, int check)
+_thr_cancel_leave(struct pthread *curthread, int check)
 {
-	THR_THREAD_LOCK(thread, thread);
-	thread->cancelflags &= ~THR_AT_CANCEL_POINT;
+	THR_LOCK(curthread);
+	curthread->cancelflags &= ~THR_AT_CANCEL_POINT;
 	/* Look for a cancellation after we unblock: */
 	if (check)
-		testcancel(thread);
-	THR_THREAD_UNLOCK(thread, thread);
+		testcancel(curthread);
+	THR_UNLOCK(curthread);
 }
 
 void
@@ -283,12 +263,12 @@
 	curthread->continuation = NULL;
 	curthread->interrupted = 0;
 
-	THR_THREAD_LOCK(curthread, curthread);
+	THR_LOCK(curthread);
 	if ((curthread->cancelflags & THR_CANCEL_NEEDED) != 0) {
 		curthread->cancelflags &= ~THR_CANCEL_NEEDED;
-		THR_THREAD_UNLOCK(curthread, curthread);
+		THR_UNLOCK(curthread);
 		_thr_exit_cleanup();
 		pthread_exit(PTHREAD_CANCELED);
 	}
-	THR_THREAD_UNLOCK(curthread, curthread);
+	THR_UNLOCK(curthread);
 }


More information about the p4-projects mailing list