From 7389a3ba16731345713638aad3e74f952392eee1 Mon Sep 17 00:00:00 2001 From: Andy Keep Date: Fri, 5 Aug 2016 00:04:00 -0400 Subject: [PATCH] - reworked the S_create_thread_object to print an error and exit when allocating the thread context fails from Sactivate_thread. before this change, the error was raised on the main thread, which resulted in strange behavior at best. also added who argument to S_create_thread_object to allow it to report either Sactivate_thread or fork-thread led to the error. externs.h, schsig.c, scheme.c, thread.c original commit: 89691cee27ee7d5e9bffae530b6346e96f8cc7ad --- LOG | 7 +++++++ c/externs.h | 2 +- c/scheme.c | 4 +++- c/schsig.c | 2 +- c/thread.c | 14 ++++++-------- 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/LOG b/LOG index 59bb0a3b42..d34fbb6c05 100644 --- a/LOG +++ b/LOG @@ -273,3 +273,10 @@ change to compile on windows. unicode is not yet supported in the windows version of the repl. c/expeditor.c +- reworked the S_create_thread_object to print an error and exit when + allocating the thread context fails from Sactivate_thread. before + this change, the error was raised on the main thread, which resulted + in strange behavior at best. also added who argument to + S_create_thread_object to allow it to report either Sactivate_thread + or fork-thread led to the error. + externs.h, schsig.c, scheme.c, thread.c diff --git a/c/externs.h b/c/externs.h index 5696a10e59..a0fbbc92c6 100644 --- a/c/externs.h +++ b/c/externs.h @@ -195,7 +195,7 @@ extern void S_new_io_init PROTO((void)); /* thread.c */ extern void S_thread_init PROTO((void)); -extern ptr S_create_thread_object PROTO((void)); +extern ptr S_create_thread_object PROTO((const char *who, ptr p_tc)); #ifdef PTHREADS extern ptr S_fork_thread PROTO((ptr thunk)); extern scheme_mutex_t *S_make_mutex PROTO((void)); diff --git a/c/scheme.c b/c/scheme.c index 205596b453..15084b3ca7 100644 --- a/c/scheme.c +++ b/c/scheme.c @@ -1053,7 +1053,9 @@ extern void Sbuild_heap(kernel, custom_init) const char *kernel; void (*custom_i S_threads = Snil; S_nthreads = 0; S_set_symbol_value(S_G.active_threads_id, FIX(0)); - tc = (ptr)THREADTC(S_create_thread_object()); + /* pass a parent tc of Svoid, since this call establishes the initial + * thread context and hence there is no parent thread context. */ + tc = (ptr)THREADTC(S_create_thread_object("startup", tc)); #ifdef PTHREADS s_thread_setspecific(S_tc_key, tc); #endif diff --git a/c/schsig.c b/c/schsig.c index 90145389c3..fbebe09ae3 100644 --- a/c/schsig.c +++ b/c/schsig.c @@ -373,7 +373,7 @@ void S_boot_error(ptr who, ptr msg, ptr args) { static void do_error(type, who, s, args) iptr type; const char *who, *s; ptr args; { ptr tc = get_thread_context(); - if (S_errors_to_console || CCHAIN(tc) == Snil) { + if (S_errors_to_console || tc == (ptr)0 || CCHAIN(tc) == Snil) { if (strlen(who) == 0) printf("Error: %s\n", s); else diff --git a/c/thread.c b/c/thread.c index 0ca73c8dcf..7e56dd04a9 100644 --- a/c/thread.c +++ b/c/thread.c @@ -47,7 +47,7 @@ void S_thread_init() { thread_find_room. main.c does part of the initialization of the base thread (e.g., parameters, current input/output ports) in one or more places. */ -ptr S_create_thread_object() { +ptr S_create_thread_object(who, p_tc) const char *who; ptr p_tc; { ptr thread, tc; INT i; @@ -56,7 +56,6 @@ ptr S_create_thread_object() { if (S_threads == Snil) { tc = (ptr)S_G.thread_context; } else { /* clone parent */ - ptr p_tc = get_thread_context(); ptr p_v = PARAMETERS(p_tc); iptr i, n = Svector_length(p_v); /* use S_vector_in to avoid thread-local allocation */ @@ -64,7 +63,7 @@ ptr S_create_thread_object() { tc = (ptr)malloc(size_tc); if (tc == (ptr)0) - S_error("fork-thread", "unable to malloc thread data structure"); + S_error(who, "unable to malloc thread data structure"); memcpy((void *)tc, (void *)p_tc, size_tc); for (i = 0; i < n; i += 1) @@ -130,14 +129,12 @@ ptr S_create_thread_object() { #ifdef PTHREADS IBOOL Sactivate_thread() { /* create or reactivate current thread */ ptr tc = get_thread_context(); + if (tc == (ptr)0) { /* thread created by someone else */ ptr thread; /* borrow base thread for now */ - tc = (ptr)S_G.thread_context; - s_thread_setspecific(S_tc_key, tc); - - thread = S_create_thread_object(); + thread = S_create_thread_object("Sactivate_thread", S_G.thread_context); s_thread_setspecific(S_tc_key, (ptr)THREADTC(thread)); return 1; } else { @@ -199,7 +196,8 @@ ptr S_fork_thread(thunk) ptr thunk; { ptr thread; int status; - thread = S_create_thread_object(); + /* pass the current thread's context as the parent thread */ + thread = S_create_thread_object("fork-thread", get_thread_context()); CP(THREADTC(thread)) = thunk; if ((status = s_thread_create(start_thread, (void *)THREADTC(thread))) != 0) {