diff options
author | Philip Chimento <philip.chimento@gmail.com> | 2019-02-24 12:51:52 -0800 |
---|---|---|
committer | Philip Chimento <philip.chimento@gmail.com> | 2019-02-24 22:04:40 -0800 |
commit | f3b84828abc7640be28d0a48e70ed60faf7fcaae (patch) | |
tree | 11e574c5de1131fe523ab64fcd18c0966d12c6a6 /gjs/native.cpp | |
parent | 304d92198d2828c42c63223733a7be87cada7bd5 (diff) | |
download | gjs-f3b84828abc7640be28d0a48e70ed60faf7fcaae.tar.gz |
native: Use static destructor to free native modules registry
Valgrind shows that the string keys used to register native modules are
leaked. (Valgrind must have gotten better at detecting this, in recent
versions.)
The simplest solution is to change the static GHashTable (which must be
freed at end of process) to a static std::unordered_map (which will have
its destructor called automatically at end of process.) Static
destructors can be tricky, but the only things being freed here are
std::string keys, so there should not be any ordering dependencies
between this and any other static destructors.
Diffstat (limited to 'gjs/native.cpp')
-rw-r--r-- | gjs/native.cpp | 39 |
1 files changed, 14 insertions, 25 deletions
diff --git a/gjs/native.cpp b/gjs/native.cpp index be77dec1..4dfe8950 100644 --- a/gjs/native.cpp +++ b/gjs/native.cpp @@ -23,31 +23,28 @@ #include <config.h> -#include <gmodule.h> +#include <string> +#include <unordered_map> -#include <util/log.h> +#include "gjs/jsapi-util.h" +#include "gjs/jsapi-wrapper.h" +#include "gjs/native.h" +#include "util/log.h" -#include "native.h" -#include "jsapi-wrapper.h" -#include "jsapi-util.h" - -static GHashTable *modules = NULL; +static std::unordered_map<std::string, GjsDefineModuleFunc> modules; void gjs_register_native_module (const char *module_id, GjsDefineModuleFunc func) { - if (modules == NULL) - modules = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); - - if (g_hash_table_lookup(modules, module_id) != NULL) { + bool inserted; + std::tie(std::ignore, inserted) = modules.insert({module_id, func}); + if (!inserted) { g_warning("A second native module tried to register the same id '%s'", module_id); return; } - g_hash_table_replace(modules, g_strdup(module_id), (void*) func); - gjs_debug(GJS_DEBUG_NATIVE, "Registered native JS module '%s'", module_id); @@ -62,10 +59,7 @@ gjs_register_native_module (const char *module_id, * builtin module without starting to try and load it. */ bool gjs_is_registered_native_module(const char* name) { - if (modules == NULL) - return false; - - return g_hash_table_lookup(modules, name) != NULL; + return modules.count(name) > 0; } /** @@ -85,23 +79,18 @@ gjs_load_native_module(JSContext *context, const char *parse_name, JS::MutableHandleObject module_out) { - GjsDefineModuleFunc func; - gjs_debug(GJS_DEBUG_NATIVE, "Defining native module '%s'", parse_name); - if (modules != NULL) - func = (GjsDefineModuleFunc) g_hash_table_lookup(modules, parse_name); - else - func = NULL; + const auto& iter = modules.find(parse_name); - if (!func) { + if (iter == modules.end()) { gjs_throw(context, "No native module '%s' has registered itself", parse_name); return false; } - return func (context, module_out); + return iter->second(context, module_out); } |