aboutsummaryrefslogtreecommitdiff
path: root/testes/libs
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2025-07-09 14:40:36 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2025-07-09 14:40:36 -0300
commit85a3c1699c9587a9e952b4ab75b1c6c310ebebea (patch)
tree67e17e9e8f74259a56690456e705a4158e5cc33e /testes/libs
parentf65d1f9e02d891733d4ff1cf8d4bc91291e0098e (diff)
downloadlua-85a3c1699c9587a9e952b4ab75b1c6c310ebebea.tar.gz
lua-85a3c1699c9587a9e952b4ab75b1c6c310ebebea.tar.bz2
lua-85a3c1699c9587a9e952b4ab75b1c6c310ebebea.zip
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.
Diffstat (limited to 'testes/libs')
-rw-r--r--testes/libs/lib22.c51
1 files changed, 51 insertions, 0 deletions
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 @@
1/* implementation for lib2-v2 */
2
3#include <string.h>
4
1#include "lua.h" 5#include "lua.h"
2#include "lauxlib.h" 6#include "lauxlib.h"
3 7
@@ -8,8 +12,54 @@ static int id (lua_State *L) {
8} 12}
9 13
10 14
15struct STR {
16 void *ud;
17 lua_Alloc allocf;
18};
19
20
21static void *t_freestr (void *ud, void *ptr, size_t osize, size_t nsize) {
22 struct STR *blk = (struct STR*)ptr - 1;
23 blk->allocf(blk->ud, blk, sizeof(struct STR) + osize, 0);
24 return NULL;
25}
26
27
28static int newstr (lua_State *L) {
29 size_t len;
30 const char *str = luaL_checklstring(L, 1, &len);
31 void *ud;
32 lua_Alloc allocf = lua_getallocf(L, &ud);
33 struct STR *blk = (struct STR*)allocf(ud, NULL, 0,
34 len + 1 + sizeof(struct STR));
35 if (blk == NULL) { /* allocation error? */
36 lua_pushliteral(L, "not enough memory");
37 lua_error(L); /* raise a memory error */
38 }
39 blk->ud = ud; blk->allocf = allocf;
40 memcpy(blk + 1, str, len + 1);
41 lua_pushexternalstring(L, (char *)(blk + 1), len, t_freestr, L);
42 return 1;
43}
44
45
46/*
47** Create an external string and keep it in the registry, so that it
48** will test that the library code is still available (to deallocate
49** this string) when closing the state.
50*/
51static void initstr (lua_State *L) {
52 lua_pushcfunction(L, newstr);
53 lua_pushstring(L,
54 "012345678901234567890123456789012345678901234567890123456789");
55 lua_call(L, 1, 1); /* call newstr("0123...") */
56 luaL_ref(L, LUA_REGISTRYINDEX); /* keep string in the registry */
57}
58
59
11static const struct luaL_Reg funcs[] = { 60static const struct luaL_Reg funcs[] = {
12 {"id", id}, 61 {"id", id},
62 {"newstr", newstr},
13 {NULL, NULL} 63 {NULL, NULL}
14}; 64};
15 65
@@ -18,6 +68,7 @@ LUAMOD_API int luaopen_lib2 (lua_State *L) {
18 lua_settop(L, 2); 68 lua_settop(L, 2);
19 lua_setglobal(L, "y"); /* y gets 2nd parameter */ 69 lua_setglobal(L, "y"); /* y gets 2nd parameter */
20 lua_setglobal(L, "x"); /* x gets 1st parameter */ 70 lua_setglobal(L, "x"); /* x gets 1st parameter */
71 initstr(L);
21 luaL_newlib(L, funcs); 72 luaL_newlib(L, funcs);
22 return 1; 73 return 1;
23} 74}