Commit f3b84828 authored by Philip Chimento's avatar Philip Chimento

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.
parent 304d9219
......@@ -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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment