diff options
-rw-r--r-- | include/gc.h | 5 | ||||
-rw-r--r-- | include/private/gc_priv.h | 6 | ||||
-rw-r--r-- | misc.c | 21 | ||||
-rw-r--r-- | tests/test.c | 1 | ||||
-rw-r--r-- | win32_threads.c | 2 |
5 files changed, 18 insertions, 17 deletions
diff --git a/include/gc.h b/include/gc.h index ec0e86fa..ebabfb08 100644 --- a/include/gc.h +++ b/include/gc.h @@ -440,6 +440,11 @@ GC_API void GC_CALL GC_atfork_child(void); /* from the main program instead. */ GC_API void GC_CALL GC_init(void); +/* Perform the collector shutdown. (E.g. dispose critical sections on */ +/* Win32 target.) A duplicate invocation is a no-op. GC_INIT should */ +/* not be called after the shutdown. See also GC_win32_free_heap(). */ +GC_API void GC_CALL GC_deinit(void); + /* General purpose allocation routines, with roughly malloc calling */ /* conv. The atomic versions promise that no relevant pointers are */ /* contained in the object. The non-atomic versions guarantee that the */ diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index 7d8e5c16..804d0948 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -1905,12 +1905,6 @@ GC_INNER GC_bool GC_try_to_collect_inner(GC_stop_func f); GC_EXTERN GC_bool GC_is_initialized; /* GC_init() has been run. */ -#if defined(MSWIN32) || defined(MSWINCE) - void GC_deinit(void); - /* Free any resources allocated by */ - /* GC_init */ -#endif - GC_INNER void GC_collect_a_little_inner(int n); /* Do n units worth of garbage */ /* collection work, if appropriate. */ @@ -1373,6 +1373,18 @@ GC_API void GC_CALL GC_enable_incremental(void) } #endif + GC_API void GC_CALL GC_deinit(void) + { + if (GC_is_initialized) { + /* Prevent duplicate resource close. */ + GC_is_initialized = FALSE; +# if defined(THREADS) && (defined(MSWIN32) || defined(MSWINCE)) + DeleteCriticalSection(&GC_write_cs); + DeleteCriticalSection(&GC_allocate_ml); +# endif + } + } + #if defined(MSWIN32) || defined(MSWINCE) # if defined(_MSC_VER) && defined(_DEBUG) && !defined(MSWINCE) @@ -1381,15 +1393,6 @@ GC_API void GC_CALL GC_enable_incremental(void) STATIC HANDLE GC_log = 0; - void GC_deinit(void) - { -# ifdef THREADS - if (GC_is_initialized) { - DeleteCriticalSection(&GC_write_cs); - } -# endif - } - # ifdef THREADS # if defined(PARALLEL_MARK) && !defined(GC_ALWAYS_MULTITHREADED) # define IF_NEED_TO_LOCK(x) if (GC_parallel || GC_need_to_lock) x diff --git a/tests/test.c b/tests/test.c index ef7e8095..ddbdd328 100644 --- a/tests/test.c +++ b/tests/test.c @@ -1868,6 +1868,7 @@ void GC_CALLBACK warn_proc(char *msg, GC_word p) UNTESTED(GC_malloc_explicitly_typed_ignore_off_page); UNTESTED(GC_debug_change_stubborn); UNTESTED(GC_debug_strndup); + UNTESTED(GC_deinit); UNTESTED(GC_strndup); UNTESTED(GC_posix_memalign); UNTESTED(GC_new_free_list); diff --git a/win32_threads.c b/win32_threads.c index 692b75b6..54fa5d2b 100644 --- a/win32_threads.c +++ b/win32_threads.c @@ -2377,7 +2377,6 @@ GC_INNER void GC_get_next_stack(char *start, char *limit, # ifdef MSWINCE GC_deinit(); - DeleteCriticalSection(&GC_allocate_ml); # endif return (int) exit_code; } @@ -2786,7 +2785,6 @@ GC_INNER void GC_thr_init(void) GC_delete_gc_thread_no_free(&dll_thread_table[i]); } GC_deinit(); - DeleteCriticalSection(&GC_allocate_ml); } break; } |