From 26f3049a86288ab37f1adcce2e25fc44a64d666b Mon Sep 17 00:00:00 2001 From: aquanight Date: Sun, 5 Jul 2020 17:20:08 -0600 Subject: [PATCH] Refactor to pure refcount for PERL_SCRIPT_REC --- src/perl/perl-core.c | 25 ++++++++++++++++--------- src/perl/perl-core.h | 7 +++---- src/perl/perl-fe.c | 2 +- src/perl/perl-signals.c | 6 ++---- src/perl/perl-sources.c | 6 ++---- 5 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/perl/perl-core.c b/src/perl/perl-core.c index 295715d3..6fd73322 100644 --- a/src/perl/perl-core.c +++ b/src/perl/perl-core.c @@ -65,7 +65,6 @@ static void perl_script_destroy_package(PERL_SCRIPT_REC *script) static void perl_script_destroy(PERL_SCRIPT_REC *script) { - perl_scripts = g_slist_remove(perl_scripts, script); signal_emit("script destroyed", 1, script); @@ -274,6 +273,7 @@ static PERL_SCRIPT_REC *script_load(char *name, const char *path, script->package = g_strdup_printf("Irssi::Script::%s", name); script->path = g_strdup(path); script->data = g_strdup(data); + script->refcount = 1; perl_scripts = g_slist_append(perl_scripts, script); signal_emit("script created", 1, script); @@ -308,6 +308,7 @@ PERL_SCRIPT_REC *perl_script_load_data(const char *data) /* Unload perl script */ void perl_script_unload(PERL_SCRIPT_REC *script) { + GSList* link; g_return_if_fail(script != NULL); perl_script_destroy_package(script); @@ -315,25 +316,31 @@ void perl_script_unload(PERL_SCRIPT_REC *script) perl_signal_remove_script(script); perl_source_remove_script(script); - script->unloaded = 1; - if (!script->active_signals) - perl_script_destroy(script); + link = g_slist_find(perl_scripts, script); + if (link != NULL) { + perl_scripts = g_slist_remove_link(perl_scripts, link); + g_slist_free(link); + perl_script_unref(script); + } + +/* perl_scripts = g_slist_remove(perl_scripts, script); + perl_script_unref(script);*/ } /* Enter a perl script (signal or input source) */ -void perl_script_enter(PERL_SCRIPT_REC *script) +void perl_script_ref(PERL_SCRIPT_REC *script) { g_return_if_fail(script != NULL); - script->active_signals++; + script->refcount++; } -void perl_script_exit(PERL_SCRIPT_REC *script) +void perl_script_unref(PERL_SCRIPT_REC *script) { g_return_if_fail(script != NULL); - script->active_signals--; - if (script->unloaded) + script->refcount--; + if (!script->refcount) perl_script_destroy(script); } diff --git a/src/perl/perl-core.h b/src/perl/perl-core.h index 5b2de9ac..6ea637ae 100644 --- a/src/perl/perl-core.h +++ b/src/perl/perl-core.h @@ -8,8 +8,7 @@ typedef struct { /* Script can be loaded from a file, or from some data in memory */ char *path; /* FILE: full path for file */ 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 */ + int refcount; /* 0 = destroy */ } PERL_SCRIPT_REC; extern GSList *perl_scripts; @@ -29,9 +28,9 @@ PERL_SCRIPT_REC *perl_script_load_data(const char *data); void perl_script_unload(PERL_SCRIPT_REC *script); /* Mark a script as entered */ -void perl_script_enter(PERL_SCRIPT_REC *script); +void perl_script_ref(PERL_SCRIPT_REC *script); /* Mark a script as exited */ -void perl_script_exit(PERL_SCRIPT_REC *script); +void perl_script_unref(PERL_SCRIPT_REC *script); /* Find loaded script by name */ PERL_SCRIPT_REC *perl_script_find(const char *name); diff --git a/src/perl/perl-fe.c b/src/perl/perl-fe.c index ba6dccce..ac84d67a 100644 --- a/src/perl/perl-fe.c +++ b/src/perl/perl-fe.c @@ -106,7 +106,7 @@ static void cmd_script_unload(const char *data) script_fix_name(name); script = perl_script_find(name); - if (script == NULL || script->unloaded) { + if (script == NULL) { printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_SCRIPT_NOT_LOADED, name); } else { diff --git a/src/perl/perl-signals.c b/src/perl/perl-signals.c index 43c992fe..f5f9d6e2 100644 --- a/src/perl/perl-signals.c +++ b/src/perl/perl-signals.c @@ -422,10 +422,9 @@ static void sig_func(const void *p1, const void *p2, rec = signal_get_user_data(); script = rec->script; - if (rec->script->unloaded) return; /* Drop signal calls into unloaded scripts. */ - perl_script_enter(script); + perl_script_ref(script); perl_call_signal(script, rec->func, signal_get_emitted_id(), args); - perl_script_exit(script); + perl_script_unref(script); } static void perl_signal_add_full_int(const char *signal, SV *func, @@ -442,7 +441,6 @@ static void perl_signal_add_full_int(const char *signal, SV *func, script = perl_script_find_package(perl_get_package()); g_return_if_fail(script != NULL); - g_return_if_fail(!script->unloaded); rec = g_new(PERL_SIGNAL_REC, 1); rec->script = script; diff --git a/src/perl/perl-sources.c b/src/perl/perl-sources.c index 16260007..69d86f1f 100644 --- a/src/perl/perl-sources.c +++ b/src/perl/perl-sources.c @@ -78,7 +78,7 @@ static int perl_source_event(PERL_SOURCE_REC *rec) PUTBACK; perl_source_ref(rec); - perl_script_enter(rec->script); + perl_script_ref(rec->script); perl_call_sv(rec->func, G_EVAL|G_DISCARD); if (SvTRUE(ERRSV)) { @@ -87,7 +87,7 @@ static int perl_source_event(PERL_SOURCE_REC *rec) g_free(error); } - perl_script_exit(rec->script); + perl_script_unref(rec->script); if (perl_source_unref(rec) && rec->once) perl_source_destroy(rec); @@ -107,7 +107,6 @@ int perl_timeout_add(int msecs, SV *func, SV *data, int once) pkg = perl_get_package(); script = perl_script_find_package(pkg); g_return_val_if_fail(script != NULL, -1); - g_return_val_if_fail(!script->unloaded, -1); rec = g_new0(PERL_SOURCE_REC, 1); perl_source_ref(rec); @@ -131,7 +130,6 @@ int perl_input_add(int source, int condition, SV *func, SV *data, int once) pkg = perl_get_package(); script = perl_script_find_package(pkg); g_return_val_if_fail(script != NULL, -1); - g_return_val_if_fail(!script->unloaded, -1); rec = g_new0(PERL_SOURCE_REC, 1); perl_source_ref(rec);