1
0
mirror of https://github.com/irssi/irssi.git synced 2024-12-04 14:46:39 -05:00

Prevent double calls of perl_script_unload

This commit is contained in:
aquanight 2020-07-05 15:31:07 -06:00
parent 6684e5cc41
commit 6012ec9e56
5 changed files with 41 additions and 5 deletions

View File

@ -67,9 +67,6 @@ static void perl_script_destroy(PERL_SCRIPT_REC *script)
{ {
perl_scripts = g_slist_remove(perl_scripts, script); perl_scripts = g_slist_remove(perl_scripts, script);
perl_signal_remove_script(script);
perl_source_remove_script(script);
signal_emit("script destroyed", 1, script); signal_emit("script destroyed", 1, script);
g_free(script->name); g_free(script->name);
@ -314,7 +311,30 @@ void perl_script_unload(PERL_SCRIPT_REC *script)
g_return_if_fail(script != NULL); g_return_if_fail(script != NULL);
perl_script_destroy_package(script); perl_script_destroy_package(script);
perl_script_destroy(script);
perl_signal_remove_script(script);
perl_source_remove_script(script);
script->unloaded = 1;
if (!script->active_signals)
perl_script_destroy(script);
}
/* Enter a perl script (signal or input source) */
void perl_script_enter(PERL_SCRIPT_REC *script)
{
g_return_if_fail(script != NULL);
script->active_signals++;
}
void perl_script_exit(PERL_SCRIPT_REC *script)
{
g_return_if_fail(script != NULL);
script->active_signals--;
if (script->unloaded)
perl_script_destroy(script);
} }
/* Find loaded script by name */ /* Find loaded script by name */

View File

@ -8,6 +8,8 @@ typedef struct {
/* Script can be loaded from a file, or from some data in memory */ /* Script can be loaded from a file, or from some data in memory */
char *path; /* FILE: full path for file */ char *path; /* FILE: full path for file */
char *data; /* DATA: data used for the script */ char *data; /* DATA: data used for the script */
int unloaded; /* Indicates unloading has been done, so it should be destroyed once all signals exit */
int active_signals; /* active signal calls into this script - prevents full teardown when nonzero */
} PERL_SCRIPT_REC; } PERL_SCRIPT_REC;
extern GSList *perl_scripts; extern GSList *perl_scripts;
@ -26,6 +28,11 @@ PERL_SCRIPT_REC *perl_script_load_data(const char *data);
/* Unload perl script */ /* Unload perl script */
void perl_script_unload(PERL_SCRIPT_REC *script); void perl_script_unload(PERL_SCRIPT_REC *script);
/* Mark a script as entered */
void perl_script_enter(PERL_SCRIPT_REC *script);
/* Mark a script as exited */
void perl_script_exit(PERL_SCRIPT_REC *script);
/* Find loaded script by name */ /* Find loaded script by name */
PERL_SCRIPT_REC *perl_script_find(const char *name); PERL_SCRIPT_REC *perl_script_find(const char *name);
/* Find loaded script by package */ /* Find loaded script by package */

View File

@ -106,7 +106,7 @@ static void cmd_script_unload(const char *data)
script_fix_name(name); script_fix_name(name);
script = perl_script_find(name); script = perl_script_find(name);
if (script == NULL) { if (script == NULL || script->unloaded) {
printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
TXT_SCRIPT_NOT_LOADED, name); TXT_SCRIPT_NOT_LOADED, name);
} else { } else {

View File

@ -420,7 +420,10 @@ static void sig_func(const void *p1, const void *p2,
args[3] = p4; args[4] = p5; args[5] = p6; args[3] = p4; args[4] = p5; args[5] = p6;
rec = signal_get_user_data(); rec = signal_get_user_data();
if (rec->script->unloaded) return; /* Drop signal calls into unloaded scripts. */
perl_script_enter(rec->script);
perl_call_signal(rec->script, rec->func, signal_get_emitted_id(), args); perl_call_signal(rec->script, rec->func, signal_get_emitted_id(), args);
perl_script_exit(rec->script);
} }
static void perl_signal_add_full_int(const char *signal, SV *func, static void perl_signal_add_full_int(const char *signal, SV *func,
@ -437,6 +440,7 @@ static void perl_signal_add_full_int(const char *signal, SV *func,
script = perl_script_find_package(perl_get_package()); script = perl_script_find_package(perl_get_package());
g_return_if_fail(script != NULL); g_return_if_fail(script != NULL);
g_return_if_fail(script->unloaded);
rec = g_new(PERL_SIGNAL_REC, 1); rec = g_new(PERL_SIGNAL_REC, 1);
rec->script = script; rec->script = script;

View File

@ -78,6 +78,7 @@ static int perl_source_event(PERL_SOURCE_REC *rec)
PUTBACK; PUTBACK;
perl_source_ref(rec); perl_source_ref(rec);
perl_script_enter(rec->script);
perl_call_sv(rec->func, G_EVAL|G_DISCARD); perl_call_sv(rec->func, G_EVAL|G_DISCARD);
if (SvTRUE(ERRSV)) { if (SvTRUE(ERRSV)) {
@ -86,6 +87,8 @@ static int perl_source_event(PERL_SOURCE_REC *rec)
g_free(error); g_free(error);
} }
perl_script_exit(rec->script);
if (perl_source_unref(rec) && rec->once) if (perl_source_unref(rec) && rec->once)
perl_source_destroy(rec); perl_source_destroy(rec);
@ -104,6 +107,7 @@ int perl_timeout_add(int msecs, SV *func, SV *data, int once)
pkg = perl_get_package(); pkg = perl_get_package();
script = perl_script_find_package(pkg); script = perl_script_find_package(pkg);
g_return_val_if_fail(script != NULL, -1); g_return_val_if_fail(script != NULL, -1);
g_return_val_if_fail(script->unloaded, -1);
rec = g_new0(PERL_SOURCE_REC, 1); rec = g_new0(PERL_SOURCE_REC, 1);
perl_source_ref(rec); perl_source_ref(rec);
@ -127,6 +131,7 @@ int perl_input_add(int source, int condition, SV *func, SV *data, int once)
pkg = perl_get_package(); pkg = perl_get_package();
script = perl_script_find_package(pkg); script = perl_script_find_package(pkg);
g_return_val_if_fail(script != NULL, -1); g_return_val_if_fail(script != NULL, -1);
g_return_val_if_fail(script->unloaded, -1);
rec = g_new0(PERL_SOURCE_REC, 1); rec = g_new0(PERL_SOURCE_REC, 1);
perl_source_ref(rec); perl_source_ref(rec);