From 85a3c1699c9587a9e952b4ab75b1c6c310ebebea Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 9 Jul 2025 14:40:36 -0300 Subject: New method to unload DLLs External strings created by DLLs may need the DLL code to be deallocated. This implies that a DLL can only be unloaded after all its strings were deallocated, which happen only after the run of all finalizers. To ensure that order, we create a 'library string' to represent each DLL and keep it locked. When this string is deallocated (after the deallocation of any string created by the DLL) it closes its corresponding DLL. --- testes/libs/lib22.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'testes/libs') diff --git a/testes/libs/lib22.c b/testes/libs/lib22.c index 8e656502..b377cce5 100644 --- a/testes/libs/lib22.c +++ b/testes/libs/lib22.c @@ -1,3 +1,7 @@ +/* implementation for lib2-v2 */ + +#include + #include "lua.h" #include "lauxlib.h" @@ -8,8 +12,54 @@ static int id (lua_State *L) { } +struct STR { + void *ud; + lua_Alloc allocf; +}; + + +static void *t_freestr (void *ud, void *ptr, size_t osize, size_t nsize) { + struct STR *blk = (struct STR*)ptr - 1; + blk->allocf(blk->ud, blk, sizeof(struct STR) + osize, 0); + return NULL; +} + + +static int newstr (lua_State *L) { + size_t len; + const char *str = luaL_checklstring(L, 1, &len); + void *ud; + lua_Alloc allocf = lua_getallocf(L, &ud); + struct STR *blk = (struct STR*)allocf(ud, NULL, 0, + len + 1 + sizeof(struct STR)); + if (blk == NULL) { /* allocation error? */ + lua_pushliteral(L, "not enough memory"); + lua_error(L); /* raise a memory error */ + } + blk->ud = ud; blk->allocf = allocf; + memcpy(blk + 1, str, len + 1); + lua_pushexternalstring(L, (char *)(blk + 1), len, t_freestr, L); + return 1; +} + + +/* +** Create an external string and keep it in the registry, so that it +** will test that the library code is still available (to deallocate +** this string) when closing the state. +*/ +static void initstr (lua_State *L) { + lua_pushcfunction(L, newstr); + lua_pushstring(L, + "012345678901234567890123456789012345678901234567890123456789"); + lua_call(L, 1, 1); /* call newstr("0123...") */ + luaL_ref(L, LUA_REGISTRYINDEX); /* keep string in the registry */ +} + + static const struct luaL_Reg funcs[] = { {"id", id}, + {"newstr", newstr}, {NULL, NULL} }; @@ -18,6 +68,7 @@ LUAMOD_API int luaopen_lib2 (lua_State *L) { lua_settop(L, 2); lua_setglobal(L, "y"); /* y gets 2nd parameter */ lua_setglobal(L, "x"); /* x gets 1st parameter */ + initstr(L); luaL_newlib(L, funcs); return 1; } -- cgit v1.2.3-55-g6feb