From 5cfb4c0919b607a1ee4e17bebeab471031cf1e15 Mon Sep 17 00:00:00 2001 From: Juan Jose Garcia Ripoll Date: Sun, 12 Oct 2008 00:26:05 +0200 Subject: [PATCH] Use of lists to keep the list of libraries is safe against threads and signal race conditions. --- src/c/alloc_2.d | 6 ++---- src/c/load.d | 50 +++++++++++++++++-------------------------------- src/c/main.d | 4 +--- src/c/threads.d | 3 ++- 4 files changed, 22 insertions(+), 41 deletions(-) diff --git a/src/c/alloc_2.d b/src/c/alloc_2.d index 25f97f273..514d52277 100644 --- a/src/c/alloc_2.d +++ b/src/c/alloc_2.d @@ -540,15 +540,13 @@ stacks_scanner() cl_object l; l = cl_core.libraries; if (l) { - int i; - for (i = 0; i < l->vector.fillp; i++) { - cl_object dll = l->vector.self.t[i]; + for (; l != Cnil; l = ECL_CONS_CDR(l)) { + cl_object dll = ECL_CONS_CAR(l); if (dll->cblock.locked) { GC_push_conditional((void *)dll, (void *)(&dll->cblock + 1), 1); GC_set_mark_bit((void *)dll); } } - GC_set_mark_bit((void *)l->vector.self.t); } GC_push_all((void *)(&cl_core), (void *)(&cl_core + 1)); GC_push_all((void *)cl_symbols, (void *)(cl_symbols + cl_num_symbols_in_core)); diff --git a/src/c/load.d b/src/c/load.d index 87be3204d..9e37a07e7 100644 --- a/src/c/load.d +++ b/src/c/load.d @@ -83,10 +83,9 @@ copy_object_file(cl_object original) static cl_object ecl_library_find_by_name(cl_object filename) { - cl_object libraries = cl_core.libraries; - cl_index i; - for (i = 0; i < libraries->vector.fillp; i++) { - cl_object other = libraries->vector.self.t[i]; + cl_object l; + for (l = cl_core.libraries; l != Cnil; l = ECL_CONS_CDR(l)) { + cl_object other = ECL_CONS_CAR(l); cl_object name = other->cblock.name; if (!Null(name) && ecl_string_eq(name, filename)) { return other; @@ -98,10 +97,9 @@ ecl_library_find_by_name(cl_object filename) static cl_object ecl_library_find_by_handle(void *handle) { - cl_object libraries = cl_core.libraries; - cl_index i; - for (i = 0; i < libraries->vector.fillp; i++) { - cl_object other = libraries->vector.self.t[i]; + cl_object l; + for (l = cl_core.libraries; l != Cnil; l = ECL_CONS_CDR(l)) { + cl_object other = ECL_CONS_CAR(l); if (handle == other->cblock.handle) { return other; } @@ -112,7 +110,6 @@ ecl_library_find_by_handle(void *handle) cl_object ecl_library_open(cl_object filename, bool force_reload) { cl_object block; - cl_object libraries = cl_core.libraries; bool self_destruct = 0; cl_index i; @@ -192,7 +189,7 @@ ecl_library_open(cl_object filename, bool force_reload) { block = other; } else { si_set_finalizer(block, Ct); - cl_vector_push_extend(2, block, libraries); + cl_core.libraries = CONS(block, cl_core.libraries); } } return block; @@ -202,16 +199,11 @@ void * ecl_library_symbol(cl_object block, const char *symbol, bool lock) { void *p; if (block == @':default') { - cl_object l = cl_core.libraries; - if (l) { - cl_index i; - for (i = 0; i < l->vector.fillp; i++) { - cl_object block = l->vector.self.t[i]; - p = ecl_library_symbol(block, symbol, lock); - if (p) { - return p; - } - } + cl_object l; + for (l = cl_core.libraries; l != Cnil; l = ECL_CONS_CDR(l)) { + cl_object block = ECL_CONS_CAR(l); + p = ecl_library_symbol(block, symbol, lock); + if (p) return p; } ecl_disable_interrupts(); #if defined(mingw32) || defined(_MSC_VER) @@ -305,7 +297,7 @@ void ecl_library_close(cl_object block) { const char *filename; bool verbose = SYM_VAL(@'si::*gc-verbose*') != Cnil; - cl_object libraries = cl_core.libraries; + cl_object l; int i; if (Null(block->cblock.name)) @@ -337,23 +329,15 @@ ecl_library_close(cl_object block) { } unlink(filename); } - for (i = 0; i < libraries->vector.fillp; i++) { - if (libraries->vector.self.t[i] == block) { - memmove(libraries->vector.self.t+i, - libraries->vector.self.t+i+1, - (libraries->vector.fillp-i-1) * sizeof(cl_object)); - libraries->vector.fillp--; - break; - } - } + cl_core.libraries = ecl_remove_eq(block, cl_core.libraries); } void ecl_library_close_all(void) { - int i; - while ((i = cl_core.libraries->vector.fillp)) - ecl_library_close(cl_core.libraries->vector.self.t[--i]); + while (cl_core.libraries != Cnil) { + ecl_library_close(ECL_CONS_CAR(cl_core.libraries)); + } } cl_object diff --git a/src/c/main.d b/src/c/main.d index c15c8bccf..5d864270c 100644 --- a/src/c/main.d +++ b/src/c/main.d @@ -389,9 +389,7 @@ cl_boot(int argc, char **argv) /* LIBRARIES is an adjustable vector of objects. It behaves as a vector of weak pointers thanks to the magic in gbc.d/alloc_2.d */ - cl_core.libraries = si_make_vector(@'t', MAKE_FIXNUM(0), - @'t', MAKE_FIXNUM(0), - @'nil', @'nil'); + cl_core.libraries = Cnil; #if 0 /* FINALIZERS and FINALIZABLE_OBJECTS are also like LIBRARIES */ cl_core.finalizable_objects = si_make_vector(@'t', MAKE_FIXNUM(512), diff --git a/src/c/threads.d b/src/c/threads.d index 30eca661b..59cae12bb 100644 --- a/src/c/threads.d +++ b/src/c/threads.d @@ -346,7 +346,8 @@ mp_exit_process(void) cl_object mp_all_processes(void) { - /* Isn't it a race condition? */ + /* No race condition here because this list is never destructively + * modified. When we add or remove processes, we create new lists. */ @(return cl_copy_list(cl_core.processes)) }