Kaydet (Commit) 9fcc4997 authored tarafından Nick Treleaven's avatar Nick Treleaven

Disconnect plugin callback signals when unloading plugins, to prevent

a segfault when emitting signals.


git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@1799 ea778897-0a13-0410-b9d1-a72fbfd435f5
üst 2fa7ce57
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
Apply patch from Jeff Pohlmeyer to add document_remove() to the Apply patch from Jeff Pohlmeyer to add document_remove() to the
plugin API (thanks). plugin API (thanks).
Add document_open_files() to plugin API. Add document_open_files() to plugin API.
* src/plugins.c:
Disconnect plugin callback signals when unloading plugins, to prevent
a segfault when emitting signals.
2007-08-14 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com> 2007-08-14 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
......
...@@ -60,6 +60,8 @@ typedef struct Plugin ...@@ -60,6 +60,8 @@ typedef struct Plugin
GModule *module; GModule *module;
gchar *filename; // plugin filename (/path/libname.so) gchar *filename; // plugin filename (/path/libname.so)
PluginFields fields; PluginFields fields;
gulong *signal_ids; // signal IDs to disconnect when unloading
gsize signal_ids_len;
PluginInfo* (*info) (); /* Returns plugin name, description */ PluginInfo* (*info) (); /* Returns plugin name, description */
void (*init) (GeanyData *data); /* Called when the plugin is enabled */ void (*init) (GeanyData *data); /* Called when the plugin is enabled */
...@@ -216,24 +218,32 @@ plugin_check_version(GModule *module) ...@@ -216,24 +218,32 @@ plugin_check_version(GModule *module)
} }
// TODO: disconnect the callbacks when the plugin is unloaded. static void add_callbacks(Plugin *plugin, GeanyCallback *callbacks)
static void add_callbacks(GeanyCallback *callbacks)
{ {
GeanyCallback *cb; GeanyCallback *cb;
guint i = 0; guint i, len = 0;
do while (TRUE)
{ {
cb = &callbacks[i]; cb = &callbacks[len];
if (!cb->signal_name || !cb->callback) if (!cb->signal_name || !cb->callback)
break; break;
len++;
}
if (len == 0)
return;
if (cb->after) plugin->signal_ids_len = len;
g_signal_connect_after(geany_object, cb->signal_name, cb->callback, cb->user_data); plugin->signal_ids = g_new(gulong, len);
else
for (i = 0; i < len; i++)
{
cb = &callbacks[i];
plugin->signal_ids[i] = (cb->after) ?
g_signal_connect_after(geany_object, cb->signal_name, cb->callback, cb->user_data) :
g_signal_connect(geany_object, cb->signal_name, cb->callback, cb->user_data); g_signal_connect(geany_object, cb->signal_name, cb->callback, cb->user_data);
i++; }
} while (TRUE);
} }
...@@ -322,7 +332,7 @@ plugin_new(const gchar *fname) ...@@ -322,7 +332,7 @@ plugin_new(const gchar *fname)
g_module_symbol(module, "geany_callbacks", (void *) &callbacks); g_module_symbol(module, "geany_callbacks", (void *) &callbacks);
if (callbacks) if (callbacks)
add_callbacks(callbacks); add_callbacks(plugin, callbacks);
geany_debug("Loaded: %s (%s)", fname, geany_debug("Loaded: %s (%s)", fname,
NVL(plugin->info()->name, "<Unknown>")); NVL(plugin->info()->name, "<Unknown>"));
...@@ -330,6 +340,19 @@ plugin_new(const gchar *fname) ...@@ -330,6 +340,19 @@ plugin_new(const gchar *fname)
} }
static void remove_callbacks(Plugin *plugin)
{
guint i;
if (plugin->signal_ids == NULL)
return;
for (i = 0; i < plugin->signal_ids_len; i++)
g_signal_handler_disconnect(geany_object, plugin->signal_ids[i]);
g_free(plugin->signal_ids);
}
static void static void
plugin_free(Plugin *plugin) plugin_free(Plugin *plugin)
{ {
...@@ -344,6 +367,7 @@ plugin_free(Plugin *plugin) ...@@ -344,6 +367,7 @@ plugin_free(Plugin *plugin)
else else
geany_debug("Unloaded: %s", plugin->filename); geany_debug("Unloaded: %s", plugin->filename);
remove_callbacks(plugin);
g_free(plugin->filename); g_free(plugin->filename);
g_free(plugin); g_free(plugin);
} }
......
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