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:
parent
d549989694
commit
8588aeec8c
lib
libc_r/uthread
libkse/thread
libpthread/thread
@ -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;
|
||||
};
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user