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