Add a new libevent_global_shutdown() to free all globals before exiting.

Mark Ellzey added a function libevent_shutdown() which calls a set of
private functions:

       * event_free_globals()
       * event_free_debug_globals()
       * event_free_debug_globals_locks()
       * event_free_evsig_globals()
       * evsig_free_globals()
       * evsig_free_globals_locks()
       * evutil_free_globals()
       * evutil_free_secure_rng_globals()
       * evutil_free_secure_rng_globals_lock()

Nick tweaked this libevent global shutdown code:

  - rename the function to emphasize that it's for global resources
  - write more in the doxygen
  - make function brace style consistent
  - add a missing void in a function definition.
This commit is contained in:
Mark Ellzey 2011-07-12 12:25:41 -04:00 committed by Nick Mathewson
parent 24dab0b359
commit 041ca00c75
8 changed files with 107 additions and 0 deletions

45
event.c
View File

@ -3124,6 +3124,51 @@ event_base_del_virtual_(struct event_base *base)
EVBASE_RELEASE_LOCK(base, th_base_lock);
}
static void
event_free_debug_globals_locks(void)
{
#ifndef EVENT__DISABLE_THREAD_SUPPORT
#ifndef EVENT__DISABLE_DEBUG_MODE
if (event_debug_map_lock_ != NULL) {
EVTHREAD_FREE_LOCK(event_debug_map_lock_, 0);
}
#endif /* EVENT__DISABLE_DEBUG_MODE */
#endif /* EVENT__DISABLE_THREAD_SUPPORT */
return;
}
static void
event_free_debug_globals(void)
{
event_free_debug_globals_locks();
}
static void
event_free_evsig_globals(void)
{
evsig_free_globals_();
}
static void
event_free_evutil_globals(void)
{
evutil_free_globals_();
}
static void
event_free_globals(void)
{
event_free_debug_globals();
event_free_evsig_globals();
event_free_evutil_globals();
}
void
libevent_global_shutdown(void)
{
event_free_globals();
}
#ifndef EVENT__DISABLE_THREAD_SUPPORT
int
event_global_setup_locks_(const int enable_locks)

View File

@ -60,5 +60,6 @@ int evsig_init_(struct event_base *);
void evsig_dealloc_(struct event_base *);
void evsig_set_base_(struct event_base *base);
void evsig_free_globals_(void);
#endif /* EVSIGNAL_INTERNAL_H_INCLUDED_ */

View File

@ -2543,3 +2543,8 @@ evutil_eventfd_(unsigned initval, int flags)
#endif
}
void
evutil_free_globals_(void)
{
evutil_free_secure_rng_globals_();
}

View File

@ -50,11 +50,13 @@ evutil_secure_rng_init(void)
(void) arc4random();
return 0;
}
#ifndef EVENT__DISABLE_THREAD_SUPPORT
int
evutil_secure_rng_global_setup_locks_(const int enable_locks)
{
return 0;
}
#endif
static void
ev_arc4random_buf(void *buf, size_t n)
@ -112,6 +114,22 @@ evutil_secure_rng_global_setup_locks_(const int enable_locks)
}
#endif
static void
evutil_free_secure_rng_globals_locks(void)
{
#ifndef EVENT__DISABLE_THREAD_SUPPORT
if (arc4rand_lock != NULL) {
EVTHREAD_FREE_LOCK(arc4rand_lock, 0);
}
#endif
return;
}
void
evutil_free_secure_rng_globals_(void) {
{
evutil_free_secure_rng_globals_locks();
}
int
evutil_secure_rng_init(void)
{

View File

@ -1310,6 +1310,22 @@ int event_base_gettimeofday_cached(struct event_base *base,
*/
int event_base_update_cache_time(struct event_base *base);
/** Release up all globally-allocated resources allocated by Libevent.
This function does not free developer-controlled resources like
event_bases, events, bufferevents, listeners, and so on. It only releases
resources like global locks that there is no other way to free.
It is not actually necessary to call this function before exit: every
resource that it frees would be released anyway on exit. It mainly exists
so that resource-leak debugging tools don't see Libevent as holding
resources at exit.
You should only call this function when no other Libevent functions will
be invoked -- e.g., when cleanly exiting a program.
*/
void libevent_global_shutdown(void);
#ifdef __cplusplus
}
#endif

View File

@ -156,6 +156,7 @@ main(int argc, char **argv)
close(socket);
unlink(fifo);
#endif
libevent_global_shutdown();
return (0);
}

View File

@ -449,6 +449,23 @@ evsig_dealloc_(struct event_base *base)
}
}
static void
evsig_free_globals_locks(void)
{
#ifndef EVENT__DISABLE_THREAD_SUPPORT
if (evsig_base_lock != NULL) {
EVTHREAD_FREE_LOCK(evsig_base_lock, 0);
}
#endif
return;
}
void
evsig_free_globals_(void)
{
evsig_free_globals_locks();
}
#ifndef EVENT__DISABLE_THREAD_SUPPORT
int
evsig_global_setup_locks_(const int enable_locks)
@ -456,4 +473,5 @@ evsig_global_setup_locks_(const int enable_locks)
EVTHREAD_SETUP_GLOBAL_LOCK(evsig_base_lock, 0);
return 0;
}
#endif

View File

@ -347,6 +347,9 @@ int evutil_hex_char_to_int_(char c);
void evutil_usleep_(const struct timeval *tv);
void evutil_free_secure_rng_globals_(void);
void evutil_free_globals_(void);
#ifdef _WIN32
HANDLE evutil_load_windows_system_library_(const TCHAR *library_name);
#endif