diff options
author | Ben Noordhuis <info@bnoordhuis.nl> | 2020-04-22 12:24:34 +0200 |
---|---|---|
committer | Ben Noordhuis <info@bnoordhuis.nl> | 2020-04-22 12:24:36 +0200 |
commit | 72fe3543feb23ae555e08628b70a3fae4da5706c (patch) | |
tree | de8a3f9515a42dc1c8bfd92d9b62a4b6bf6c9b4e /src | |
parent | b29612fe59f664d9b370dceda1060b1dc1deaff0 (diff) | |
download | libuv-72fe3543feb23ae555e08628b70a3fae4da5706c.tar.gz libuv-72fe3543feb23ae555e08628b70a3fae4da5706c.zip |
unix,win: add uv_library_shutdown()
Make it possible to explicitly tell libuv to release any resources
it's still holding onto (memory, threads, file descriptors, etc.)
Before this commit, cleanup was performed in various destructors.
This commit centralizes the cleanup logic, enabling the addition of
`uv_library_shutdown()`, but maintains the current observable behavior
of cleaning up when libuv is unloaded by means of `dlclose(3)`.
Fixes: https://github.com/libuv/libuv/issues/2763
PR-URL: https://github.com/libuv/libuv/pull/2764
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/threadpool.c | 4 | ||||
-rw-r--r-- | src/unix/aix.c | 2 | ||||
-rw-r--r-- | src/unix/bsd-proctitle.c | 7 | ||||
-rw-r--r-- | src/unix/internal.h | 2 | ||||
-rw-r--r-- | src/unix/no-proctitle.c | 3 | ||||
-rw-r--r-- | src/unix/proctitle.c | 2 | ||||
-rw-r--r-- | src/unix/signal.c | 4 | ||||
-rw-r--r-- | src/uv-common.c | 16 | ||||
-rw-r--r-- | src/uv-common.h | 4 | ||||
-rw-r--r-- | src/win/signal.c | 5 | ||||
-rw-r--r-- | src/win/util.c | 4 |
11 files changed, 45 insertions, 8 deletions
diff --git a/src/threadpool.c b/src/threadpool.c index a8f433f0..0998938f 100644 --- a/src/threadpool.c +++ b/src/threadpool.c @@ -160,8 +160,8 @@ static void post(QUEUE* q, enum uv__work_kind kind) { } +void uv__threadpool_cleanup(void) { #ifndef _WIN32 -UV_DESTRUCTOR(static void cleanup(void)) { unsigned int i; if (nthreads == 0) @@ -181,8 +181,8 @@ UV_DESTRUCTOR(static void cleanup(void)) { threads = NULL; nthreads = 0; -} #endif +} static void init_threads(void) { diff --git a/src/unix/aix.c b/src/unix/aix.c index 417ee551..6b4594b4 100644 --- a/src/unix/aix.c +++ b/src/unix/aix.c @@ -926,7 +926,7 @@ int uv_get_process_title(char* buffer, size_t size) { } -UV_DESTRUCTOR(static void free_args_mem(void)) { +void uv__process_title_cleanup(void) { uv__free(args_mem); /* Keep valgrind happy. */ args_mem = NULL; } diff --git a/src/unix/bsd-proctitle.c b/src/unix/bsd-proctitle.c index 0ce47c8f..723b81c0 100644 --- a/src/unix/bsd-proctitle.c +++ b/src/unix/bsd-proctitle.c @@ -37,6 +37,13 @@ static void init_process_title_mutex_once(void) { } +void uv__process_title_cleanup(void) { + /* TODO(bnoordhuis) uv_mutex_destroy(&process_title_mutex) + * and reset process_title_mutex_once? + */ +} + + char** uv_setup_args(int argc, char** argv) { process_title = argc > 0 ? uv__strdup(argv[0]) : NULL; return argv; diff --git a/src/unix/internal.h b/src/unix/internal.h index 598554b6..402ee877 100644 --- a/src/unix/internal.h +++ b/src/unix/internal.h @@ -106,10 +106,8 @@ int uv__pthread_sigmask(int how, const sigset_t* set, sigset_t* oset); #if defined(__clang__) || \ defined(__GNUC__) || \ defined(__INTEL_COMPILER) -# define UV_DESTRUCTOR(declaration) __attribute__((destructor)) declaration # define UV_UNUSED(declaration) __attribute__((unused)) declaration #else -# define UV_DESTRUCTOR(declaration) declaration # define UV_UNUSED(declaration) declaration #endif diff --git a/src/unix/no-proctitle.c b/src/unix/no-proctitle.c index 165740ca..32aa0af1 100644 --- a/src/unix/no-proctitle.c +++ b/src/unix/no-proctitle.c @@ -29,6 +29,9 @@ char** uv_setup_args(int argc, char** argv) { return argv; } +void uv__process_title_cleanup(void) { +} + int uv_set_process_title(const char* title) { return 0; } diff --git a/src/unix/proctitle.c b/src/unix/proctitle.c index d124d3c7..4ee991fc 100644 --- a/src/unix/proctitle.c +++ b/src/unix/proctitle.c @@ -145,7 +145,7 @@ int uv_get_process_title(char* buffer, size_t size) { } -UV_DESTRUCTOR(static void free_args_mem(void)) { +void uv__process_title_cleanup(void) { uv__free(args_mem); /* Keep valgrind happy. */ args_mem = NULL; } diff --git a/src/unix/signal.c b/src/unix/signal.c index 1e7e8ac5..1c83e095 100644 --- a/src/unix/signal.c +++ b/src/unix/signal.c @@ -77,7 +77,7 @@ static void uv__signal_global_init(void) { } -UV_DESTRUCTOR(static void uv__signal_global_fini(void)) { +void uv__signal_cleanup(void) { /* We can only use signal-safe functions here. * That includes read/write and close, fortunately. * We do all of this directly here instead of resetting @@ -98,7 +98,7 @@ UV_DESTRUCTOR(static void uv__signal_global_fini(void)) { static void uv__signal_global_reinit(void) { - uv__signal_global_fini(); + uv__signal_cleanup(); if (uv__make_pipe(uv__signal_lock_pipefd, 0)) abort(); diff --git a/src/uv-common.c b/src/uv-common.c index 5cb1a8c8..f69a2c1d 100644 --- a/src/uv-common.c +++ b/src/uv-common.c @@ -821,3 +821,19 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { uv__free(cpu_infos); } + + +#ifdef __GNUC__ /* Also covers __clang__ and __INTEL_COMPILER. */ +__attribute__((destructor)) +#endif +void uv_library_shutdown(void) { + static int was_shutdown; + + if (was_shutdown) + return; + + uv__process_title_cleanup(); + uv__signal_cleanup(); + uv__threadpool_cleanup(); + was_shutdown = 1; +} diff --git a/src/uv-common.h b/src/uv-common.h index f08fb8ae..28cc852c 100644 --- a/src/uv-common.h +++ b/src/uv-common.h @@ -201,6 +201,10 @@ int uv__next_timeout(const uv_loop_t* loop); void uv__run_timers(uv_loop_t* loop); void uv__timer_close(uv_timer_t* handle); +void uv__process_title_cleanup(void); +void uv__signal_cleanup(void); +void uv__threadpool_cleanup(void); + #define uv__has_active_reqs(loop) \ ((loop)->active_reqs.count > 0) diff --git a/src/win/signal.c b/src/win/signal.c index 276dc609..3d9f92cf 100644 --- a/src/win/signal.c +++ b/src/win/signal.c @@ -46,6 +46,11 @@ void uv_signals_init(void) { } +void uv__signal_cleanup(void) { + /* TODO(bnoordhuis) Undo effects of uv_signal_init()? */ +} + + static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) { /* Compare signums first so all watchers with the same signnum end up * adjacent. */ diff --git a/src/win/util.c b/src/win/util.c index aaa7ba03..ff8a28b4 100644 --- a/src/win/util.c +++ b/src/win/util.c @@ -361,6 +361,10 @@ char** uv_setup_args(int argc, char** argv) { } +void uv__process_title_cleanup(void) { +} + + int uv_set_process_title(const char* title) { int err; int length; |