the upcoming 2.0 version
https://redmine.lighttpd.net/projects/lighttpd2
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
154 lines
3.5 KiB
154 lines
3.5 KiB
|
|
#include <lighttpd/module.h> |
|
|
|
liModules *li_modules_new(gpointer main, const gchar *module_dir, gboolean module_resident) { |
|
liModules *m = g_slice_new(liModules); |
|
|
|
m->version = MODULE_VERSION; |
|
m->main = main; |
|
m->mods = g_array_new(FALSE, TRUE, sizeof(liModule*)); |
|
m->module_dir = g_strdup(module_dir); |
|
m->module_resident = module_resident; |
|
m->sizeof_off_t = sizeof(off_t); |
|
|
|
return m; |
|
} |
|
|
|
liModule *li_module_lookup(liModules *mods, const gchar *name) { |
|
liModule *mod; |
|
GArray *a = mods->mods; |
|
|
|
for (guint i = 0; i < a->len; i++) { |
|
mod = g_array_index(a, liModule*, i); |
|
if (mod != NULL && g_str_equal(mod->name->str, name)) |
|
return mod; |
|
} |
|
|
|
return NULL; |
|
} |
|
|
|
void li_modules_free(liModules* mods) { |
|
/* unload all modules */ |
|
GArray *a = mods->mods; |
|
liModule *mod; |
|
|
|
for (guint i = 0; i < a->len; i++) { |
|
mod = g_array_index(a, liModule*, i); |
|
if (!mod) |
|
continue; |
|
li_module_release(mods, mod); |
|
} |
|
|
|
g_array_free(mods->mods, TRUE); |
|
g_free(mods->module_dir); |
|
g_slice_free(liModules, mods); |
|
} |
|
|
|
|
|
liModule* li_module_load(liModules *mods, const gchar* name) { |
|
liModule *mod; |
|
liModuleInitCB m_init; |
|
GString *m_init_str, *m_free_str; |
|
guint i; |
|
|
|
mod = li_module_lookup(mods, name); |
|
|
|
if (mod) { |
|
/* module already loaded, increment refcount and return */ |
|
mod->refcount++; |
|
return mod; |
|
} |
|
|
|
mod = g_slice_new0(liModule); |
|
mod->name = g_string_new(name); |
|
mod->refcount = 1; |
|
mod->path = g_module_build_path(mods->module_dir, name); |
|
|
|
mod->module = g_module_open(mod->path, G_MODULE_BIND_LAZY); |
|
|
|
if (!mod->module) { |
|
g_string_free(mod->name, TRUE); |
|
g_free(mod->path); |
|
g_slice_free(liModule, mod); |
|
return NULL; |
|
} |
|
|
|
/* temporary strings for mod_xyz_init and mod_xyz_free */ |
|
m_init_str = g_string_new(name); |
|
g_string_append_len(m_init_str, CONST_STR_LEN("_init")); |
|
m_free_str = g_string_new(name); |
|
g_string_append_len(m_free_str, CONST_STR_LEN("_free")); |
|
|
|
if (!g_module_symbol(mod->module, m_init_str->str, (gpointer *)&m_init) |
|
|| !g_module_symbol(mod->module, m_free_str->str, (gpointer *)&mod->free) |
|
|| m_init == NULL || mod->free == NULL) { |
|
|
|
/* mod_init or mod_free couldn't be located, something went wrong */ |
|
g_string_free(m_init_str, TRUE); |
|
g_string_free(m_free_str, TRUE); |
|
g_free(mod->path); |
|
g_string_free(mod->name, TRUE); |
|
g_slice_free(liModule, mod); |
|
return NULL; |
|
} |
|
|
|
/* call mod_xyz_init */ |
|
if (!m_init(mods, mod)) { |
|
g_string_free(m_init_str, TRUE); |
|
g_string_free(m_free_str, TRUE); |
|
g_free(mod->path); |
|
g_string_free(mod->name, TRUE); |
|
g_slice_free(liModule, mod); |
|
return NULL; |
|
} |
|
|
|
if (mods->module_resident) |
|
g_module_make_resident(mod->module); |
|
|
|
/* insert into free slot */ |
|
for (i = 0; i < mods->mods->len; i++) { |
|
if (!g_array_index(mods->mods, liModule*, i)) |
|
{ |
|
g_array_index(mods->mods, liModule*, i) = mod; |
|
break; |
|
} |
|
} |
|
|
|
/* if no free slot was found, append */ |
|
if (i == mods->mods->len) |
|
g_array_append_val(mods->mods, mod); |
|
|
|
/* free temp strings */ |
|
g_string_free(m_free_str, TRUE); |
|
g_string_free(m_init_str, TRUE); |
|
|
|
return mod; |
|
} |
|
|
|
void li_module_release(liModules *mods, liModule *mod) { |
|
guint i; |
|
|
|
if (--mod->refcount > 0) |
|
return; |
|
|
|
for (i = 0; i < mods->mods->len; i++) { |
|
if (g_array_index(mods->mods, liModule*, i) == mod) |
|
{ |
|
g_array_index(mods->mods, liModule*, i) = NULL; |
|
break; |
|
} |
|
} |
|
|
|
mod->free(mods, mod); |
|
g_module_close(mod->module); |
|
g_free(mod->path); |
|
g_string_free(mod->name, TRUE); |
|
g_slice_free(liModule, mod); |
|
} |
|
|
|
void li_module_release_name(liModules *mods, const gchar* name) { |
|
liModule *mod = li_module_lookup(mods, name); |
|
|
|
if (mod) |
|
li_module_release(mods, mod); |
|
}
|
|
|