Fix a bug in canceling joining threads.

Do not detach canceled threads.

Reported by:		Arno Klaassen <arno@heho.snv.jussieu.fr>
Collaboration with:	deischen
This commit is contained in:
Jason Evans 2001-08-16 06:31:32 +00:00
parent d549989694
commit 8588aeec8c
9 changed files with 54 additions and 6 deletions

@ -575,6 +575,7 @@ union pthread_wait_data {
FILE *fp;
struct pthread_poll_data *poll_data;
spinlock_t *spinlock;
struct pthread *thread;
};
/*

@ -64,9 +64,23 @@ _pthread_cancel(pthread_t pthread)
break;
case PS_JOIN:
/*
* Disconnect the thread from the joinee and
* detach:
*/
if (pthread->data.thread != NULL) {
pthread->data.thread->joiner = NULL;
pthread_detach((pthread_t)
pthread->data.thread);
}
pthread->cancelflags |= PTHREAD_CANCELLING;
PTHREAD_NEW_STATE(pthread, PS_RUNNING);
break;
case PS_SUSPENDED:
if (pthread->suspended == SUSP_NO ||
pthread->suspended == SUSP_YES ||
pthread->suspended == SUSP_JOIN ||
pthread->suspended == SUSP_NOWAIT) {
/*
* This thread isn't in any scheduling
@ -189,7 +203,6 @@ _pthread_testcancel(void)
*/
curthread->cancelflags &= ~PTHREAD_CANCELLING;
_thread_exit_cleanup();
pthread_detach((pthread_t)curthread);
pthread_exit(PTHREAD_CANCELED);
PANIC("cancel");
}
@ -226,7 +239,6 @@ finish_cancellation(void *arg)
if ((curthread->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) {
curthread->cancelflags &= ~PTHREAD_CANCEL_NEEDED;
_thread_exit_cleanup();
pthread_detach((pthread_t)curthread);
pthread_exit(PTHREAD_CANCELED);
}
}

@ -121,6 +121,9 @@ _pthread_join(pthread_t pthread, void **thread_return)
/* Set the running thread to be the joiner: */
pthread->joiner = curthread;
/* Keep track of which thread we're joining to: */
curthread->data.thread = pthread;
/* Schedule the next thread: */
_thread_kern_sched_state(PS_JOIN, __FILE__, __LINE__);

@ -64,9 +64,23 @@ _pthread_cancel(pthread_t pthread)
break;
case PS_JOIN:
/*
* Disconnect the thread from the joinee and
* detach:
*/
if (pthread->data.thread != NULL) {
pthread->data.thread->joiner = NULL;
pthread_detach((pthread_t)
pthread->data.thread);
}
pthread->cancelflags |= PTHREAD_CANCELLING;
PTHREAD_NEW_STATE(pthread, PS_RUNNING);
break;
case PS_SUSPENDED:
if (pthread->suspended == SUSP_NO ||
pthread->suspended == SUSP_YES ||
pthread->suspended == SUSP_JOIN ||
pthread->suspended == SUSP_NOWAIT) {
/*
* This thread isn't in any scheduling
@ -189,7 +203,6 @@ _pthread_testcancel(void)
*/
curthread->cancelflags &= ~PTHREAD_CANCELLING;
_thread_exit_cleanup();
pthread_detach((pthread_t)curthread);
pthread_exit(PTHREAD_CANCELED);
PANIC("cancel");
}
@ -226,7 +239,6 @@ finish_cancellation(void *arg)
if ((curthread->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) {
curthread->cancelflags &= ~PTHREAD_CANCEL_NEEDED;
_thread_exit_cleanup();
pthread_detach((pthread_t)curthread);
pthread_exit(PTHREAD_CANCELED);
}
}

@ -121,6 +121,9 @@ _pthread_join(pthread_t pthread, void **thread_return)
/* Set the running thread to be the joiner: */
pthread->joiner = curthread;
/* Keep track of which thread we're joining to: */
curthread->data.thread = pthread;
/* Schedule the next thread: */
_thread_kern_sched_state(PS_JOIN, __FILE__, __LINE__);

@ -575,6 +575,7 @@ union pthread_wait_data {
FILE *fp;
struct pthread_poll_data *poll_data;
spinlock_t *spinlock;
struct pthread *thread;
};
/*

@ -64,9 +64,23 @@ _pthread_cancel(pthread_t pthread)
break;
case PS_JOIN:
/*
* Disconnect the thread from the joinee and
* detach:
*/
if (pthread->data.thread != NULL) {
pthread->data.thread->joiner = NULL;
pthread_detach((pthread_t)
pthread->data.thread);
}
pthread->cancelflags |= PTHREAD_CANCELLING;
PTHREAD_NEW_STATE(pthread, PS_RUNNING);
break;
case PS_SUSPENDED:
if (pthread->suspended == SUSP_NO ||
pthread->suspended == SUSP_YES ||
pthread->suspended == SUSP_JOIN ||
pthread->suspended == SUSP_NOWAIT) {
/*
* This thread isn't in any scheduling
@ -189,7 +203,6 @@ _pthread_testcancel(void)
*/
curthread->cancelflags &= ~PTHREAD_CANCELLING;
_thread_exit_cleanup();
pthread_detach((pthread_t)curthread);
pthread_exit(PTHREAD_CANCELED);
PANIC("cancel");
}
@ -226,7 +239,6 @@ finish_cancellation(void *arg)
if ((curthread->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) {
curthread->cancelflags &= ~PTHREAD_CANCEL_NEEDED;
_thread_exit_cleanup();
pthread_detach((pthread_t)curthread);
pthread_exit(PTHREAD_CANCELED);
}
}

@ -121,6 +121,9 @@ _pthread_join(pthread_t pthread, void **thread_return)
/* Set the running thread to be the joiner: */
pthread->joiner = curthread;
/* Keep track of which thread we're joining to: */
curthread->data.thread = pthread;
/* Schedule the next thread: */
_thread_kern_sched_state(PS_JOIN, __FILE__, __LINE__);

@ -575,6 +575,7 @@ union pthread_wait_data {
FILE *fp;
struct pthread_poll_data *poll_data;
spinlock_t *spinlock;
struct pthread *thread;
};
/*