Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions lgi/callable.c
Original file line number Diff line number Diff line change
Expand Up @@ -1429,6 +1429,15 @@ closure_callback (ffi_cif *cif, void *ret, void **args, void *closure_arg)
/* This is NOT called by Lua, so we better leave the Lua stack we
used pretty much tidied. */
lua_settop (L, stacktop);

/* For autodestroy closures, nudge Lua's GC after resetting the stack.
ffi_closure_alloc() memory is invisible to Lua's allocator, so GC
does not naturally respond to ffi memory pressure. A single step
here ensures the guard created above is finalized promptly, which in
turn allows the callback's Lua closure chain to be freed. */
if (closure->autodestroy)
lua_gc (block->callback.L, LUA_GCSTEP, 10);

if (L != marshal_L)
lua_settop (marshal_L, 0);

Expand Down
16 changes: 15 additions & 1 deletion lgi/marshal.c
Original file line number Diff line number Diff line change
Expand Up @@ -915,8 +915,22 @@ marshal_2c_callable (lua_State *L, GICallableInfo *ci, GIArgInfo *ai,
*lgi_guard_create (L, lgi_closure_destroy) = user_data;
nret++;
}
else if (scope == GI_SCOPE_TYPE_ASYNC || scope == GI_SCOPE_TYPE_NOTIFIED)
{
/* ASYNC: callback fired once, autodestroy cleans up.
NOTIFIED without destroy param: no destroy will come; treat as
autodestroy and warn since this is unusual. */
if (scope == GI_SCOPE_TYPE_NOTIFIED)
g_warning ("lgi: NOTIFIED-scope callback without destroy parameter;"
" treating as autodestroy");
}
else if (scope == GI_SCOPE_TYPE_FOREVER)
{
/* Intentionally no cleanup: callback lives until process exit. */
}
else
g_assert (scope == GI_SCOPE_TYPE_ASYNC);
g_warning ("lgi: unexpected scope type %d for callback without "
"user_data; closure may leak", (int) scope);
}

/* Create the closure. */
Expand Down