summaryrefslogtreecommitdiff
path: root/gjs/native.cpp
diff options
context:
space:
mode:
authorPhilip Chimento <philip.chimento@gmail.com>2019-02-24 12:51:52 -0800
committerPhilip Chimento <philip.chimento@gmail.com>2019-02-24 22:04:40 -0800
commitf3b84828abc7640be28d0a48e70ed60faf7fcaae (patch)
tree11e574c5de1131fe523ab64fcd18c0966d12c6a6 /gjs/native.cpp
parent304d92198d2828c42c63223733a7be87cada7bd5 (diff)
downloadgjs-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.cpp39
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);
}