diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2025-07-09 14:40:36 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2025-07-09 14:40:36 -0300 |
| commit | 85a3c1699c9587a9e952b4ab75b1c6c310ebebea (patch) | |
| tree | 67e17e9e8f74259a56690456e705a4158e5cc33e /testes/libs | |
| parent | f65d1f9e02d891733d4ff1cf8d4bc91291e0098e (diff) | |
| download | lua-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.c | 51 |
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 | ||
| 15 | struct STR { | ||
| 16 | void *ud; | ||
| 17 | lua_Alloc allocf; | ||
| 18 | }; | ||
| 19 | |||
| 20 | |||
| 21 | static 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 | |||
| 28 | static 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 | */ | ||
| 51 | static 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 | |||
| 11 | static const struct luaL_Reg funcs[] = { | 60 | static 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 | } |
