thread-terminate should set an exception in the thread

This commit is contained in:
Alex Shinn 2014-12-27 14:51:12 +09:00
parent 0cce37aaa8
commit 429704a5f6
3 changed files with 8 additions and 0 deletions

2
eval.c
View file

@ -492,6 +492,8 @@ void sexp_init_eval_context_globals (sexp ctx) {
= sexp_user_exception(ctx, SEXP_FALSE, "I/O would block", SEXP_NULL); = sexp_user_exception(ctx, SEXP_FALSE, "I/O would block", SEXP_NULL);
sexp_global(ctx, SEXP_G_IO_BLOCK_ONCE_ERROR) sexp_global(ctx, SEXP_G_IO_BLOCK_ONCE_ERROR)
= sexp_user_exception(ctx, SEXP_FALSE, "I/O would block once", SEXP_NULL); = sexp_user_exception(ctx, SEXP_FALSE, "I/O would block once", SEXP_NULL);
sexp_global(ctx, SEXP_G_THREAD_TERMINATE_ERROR)
= sexp_user_exception(ctx, SEXP_FALSE, "thread terminated", SEXP_NULL);
sexp_global(ctx, SEXP_G_THREADS_FRONT) = SEXP_NULL; sexp_global(ctx, SEXP_G_THREADS_FRONT) = SEXP_NULL;
sexp_global(ctx, SEXP_G_THREADS_BACK) = SEXP_NULL; sexp_global(ctx, SEXP_G_THREADS_BACK) = SEXP_NULL;
sexp_global(ctx, SEXP_G_THREADS_SIGNALS) = SEXP_ZERO; sexp_global(ctx, SEXP_G_THREADS_SIGNALS) = SEXP_ZERO;

View file

@ -1235,6 +1235,7 @@ enum sexp_context_globals {
#if SEXP_USE_GREEN_THREADS #if SEXP_USE_GREEN_THREADS
SEXP_G_IO_BLOCK_ERROR, SEXP_G_IO_BLOCK_ERROR,
SEXP_G_IO_BLOCK_ONCE_ERROR, SEXP_G_IO_BLOCK_ONCE_ERROR,
SEXP_G_THREAD_TERMINATE_ERROR,
SEXP_G_THREADS_SCHEDULER, SEXP_G_THREADS_SCHEDULER,
SEXP_G_THREADS_FRONT, SEXP_G_THREADS_FRONT,
SEXP_G_THREADS_BACK, SEXP_G_THREADS_BACK,

View file

@ -138,8 +138,13 @@ static int sexp_delete_list (sexp ctx, int global, sexp x) {
sexp sexp_thread_terminate (sexp ctx, sexp self, sexp_sint_t n, sexp thread) { sexp sexp_thread_terminate (sexp ctx, sexp self, sexp_sint_t n, sexp thread) {
sexp res = sexp_make_boolean(ctx == thread); sexp res = sexp_make_boolean(ctx == thread);
sexp_assert_type(ctx, sexp_contextp, SEXP_CONTEXT, thread);
/* terminate the thread and all children */ /* terminate the thread and all children */
for ( ; thread && sexp_contextp(thread); thread=sexp_context_child(thread)) { for ( ; thread && sexp_contextp(thread); thread=sexp_context_child(thread)) {
/* if not already terminated set an exception status */
sexp_context_errorp(thread) = 1;
sexp_context_result(thread) =
sexp_global(ctx, SEXP_G_THREAD_TERMINATE_ERROR);
/* zero the refuel - this tells the scheduler the thread is terminated */ /* zero the refuel - this tells the scheduler the thread is terminated */
sexp_context_refuel(thread) = 0; sexp_context_refuel(thread) = 0;
/* unblock the thread if needed so it can be scheduled and terminated */ /* unblock the thread if needed so it can be scheduled and terminated */