diff --git a/doc/events.txt b/doc/events.txt index 41c64f2d..e7d8397b 100644 --- a/doc/events.txt +++ b/doc/events.txt @@ -113,6 +113,26 @@ Description: Open Lua console dialog. +------------------------------------------------------------------------------- +Name: flush-caches +Managed By: The scripting subsystem/backends +Triggered When: + + Elinks is going to free its caches. This happens when the user chooses + ACT_MAIN_CACHE_MINIMIZE, but currently also on ACT_MAIN_FORGET_CREDENTIALS + and when ELinks is quitting. + +Arguments: + + None + +Description: + + If scripting backends hold pointers to cache entries, they should try + to release those pointers so that ELinks can free the entries. This + may involve a full garbage collection. Also, if backends have some + caches of their own, they should flush them. + ------------------------------------------------------------------------------- Name: follow-url Managed By: The scripting subsystem/backends diff --git a/src/main/main.c b/src/main/main.c index 5b2bec8e..a78e0b20 100644 --- a/src/main/main.c +++ b/src/main/main.c @@ -315,6 +315,13 @@ terminate_all_subsystems(void) void shrink_memory(int whole) { +#ifdef CONFIG_SCRIPTING + /* The SMJS pre-format-html hook constructs an SMJS object for + * each cache entry. Give all scripting modules a cue to garbage + * collect any such objects so that the entries can be freed. */ + if (whole) + trigger_event_name("flush-caches"); +#endif shrink_dns_cache(whole); shrink_format_cache(whole); garbage_collection(whole); diff --git a/src/scripting/smjs/hooks.c b/src/scripting/smjs/hooks.c index 03097ef0..c287659f 100644 --- a/src/scripting/smjs/hooks.c +++ b/src/scripting/smjs/hooks.c @@ -122,10 +122,26 @@ end: return ret; } +static enum evhook_status +script_hook_flush_caches(va_list ap, void *data) +{ + /* script_hook_pre_format_html() calls smjs_get_cache_entry_object() + * for each struct cache_entry. The resulting SMJS objects hold + * references to the structs, and these references prevent ELinks + * from freeing the cache entries. (The resource info dialog shows + * that the entries are "in use".) SMJS does not immediately collect + * these objects as garbage. If we're really trying to flush the + * caches then ask SMJS to run a check. */ + if (smjs_ctx) + JS_GC(smjs_ctx); + return EVENT_HOOK_STATUS_NEXT; +} + struct event_hook_info smjs_scripting_hooks[] = { { "goto-url", 0, script_hook_goto_url, NULL }, { "follow-url", 0, script_hook_follow_url, NULL }, { "pre-format-html", 0, script_hook_pre_format_html, NULL }, + { "flush-caches", 0, script_hook_flush_caches, NULL }, NULL_EVENT_HOOK_INFO, };