summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/gc.h5
-rw-r--r--include/private/gc_priv.h6
-rw-r--r--misc.c21
-rw-r--r--tests/test.c1
-rw-r--r--win32_threads.c2
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. */
diff --git a/misc.c b/misc.c
index 7bf4ba73..e833f37e 100644
--- a/misc.c
+++ b/misc.c
@@ -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;
}