diff options
| author | ame <[email protected]> | 2024-05-25 04:08:59 -0500 |
|---|---|---|
| committer | ame <[email protected]> | 2024-05-25 04:08:59 -0500 |
| commit | 237fcfbd61a9895326538a274f025d9ed57a3903 (patch) | |
| tree | 44c36c7d38ae68f562a0290c26bae4a79ab87f1e | |
| parent | 8d169e81694b587a425993cb11297e8a9183b37c (diff) | |
fixed deepcopy
| -rw-r--r-- | docs/thread.md | 45 | ||||
| -rw-r--r-- | src/io.c | 2 | ||||
| -rw-r--r-- | src/lua.c | 108 | ||||
| -rw-r--r-- | src/lua.h | 2 | ||||
| -rw-r--r-- | src/net.c | 2 | ||||
| -rw-r--r-- | src/thread.c | 97 | ||||
| -rw-r--r-- | src/thread.h | 4 | ||||
| -rw-r--r-- | tests/h.lua | 31 | ||||
| -rw-r--r-- | tests/net.lua | 8 |
9 files changed, 213 insertions, 86 deletions
diff --git a/docs/thread.md b/docs/thread.md index 9f868cb..00619ea 100644 --- a/docs/thread.md +++ b/docs/thread.md @@ -1,5 +1,50 @@ # threads **
+## buffer
+
+'takes 'anything'
+
+a thread-safe object buffer to easily transfer things between threads
+
+full example:
+
+```lua
+buffer = llib.thread.buffer({2, 3, 4})
+buffer:get() --{2, 3, 4}
+...
+buffer:set({3, 4, 5}) --get is now {3, 4, 5}
+...
+buffer:mod(function(obj)
+ for i=1,#obj do
+ obj[i] = obj[i] + 1
+ end
+ return obj
+end) --is now {4, 5, 6}
+...
+buffer:clean() -- calls __gc early
+```
+
+### get
+
+returns copy of the value in the buffer
+
+### set
+
+'takes 'anything'
+
+sets the value in the buffer
+
+### mod
+
+'takes a function, one parameter, one returns
+
+passes a copy of the value of the buffer, and sets the buffer to the value returned
+
+```lua
+buffer:mod(function(obj) return 5)
+--is the same as
+buffer:set(5)
+```
## lock, unlock
'takes an integer
@@ -137,7 +137,7 @@ void i_pprint(lua_State* L, int indent, int skip_indent){ break; case LUA_TFUNCTION: if(!skip_indent) print_indentation(indent); - printf(color_yellow"(%p)"color_reset, lua_topointer(L, -1)); + printf(color_yellow"(fn,%p)"color_reset, lua_topointer(L, -1)); break; case LUA_TUSERDATA: if(!skip_indent) print_indentation(indent); @@ -40,8 +40,9 @@ int writer(lua_State *L, const void* p, size_t sz, void* ud){ * @param {lua_State*} source
* @param {lua_State*} dest
* @param {void*} items already visited, use NULL
+ * @param {int} whether or not to skip meta data
*/
-void i_dcopy(lua_State* src, lua_State* dest, void* _seen){
+void luaI_deepcopy(lua_State* src, lua_State* dest, void* _seen, int skip_meta){
parray_t* seen = (parray_t*)_seen;
int wnull = seen == NULL;
if(wnull) seen = parray_init();
@@ -54,7 +55,8 @@ void i_dcopy(lua_State* src, lua_State* dest, void* _seen){ void* whar;
double n;
int old_top = lua_gettop(src);
- //printf("%i\n",ii++);
+ int modi = 0;
+
switch(lua_type(src, -1)){
case LUA_TNUMBER:
n = luaL_checknumber(src, -1);
@@ -66,96 +68,82 @@ void i_dcopy(lua_State* src, lua_State* dest, void* _seen){ lua_pushlstring(dest, s, len);
break;
case LUA_TTABLE:
+ modi = 1;
lua_newtable(dest);
at = lua_gettop(dest);
at2 = lua_gettop(src);
char aauwu[50] = {0};
sprintf(aauwu, "%p", lua_topointer(src, at2));
- //int* sp = malloc(1);
whar = parray_get(seen, aauwu);
- if( whar != NULL){
- //printf("%s\n",lua_tostring(src, at2 - 1));
- //printf("WHAR\n");
+ if(whar != NULL){
lua_pop(dest, 1);
lua_rawgeti(dest, LUA_REGISTRYINDEX, *(int*)whar);
-
-
return;
}
int *sp = malloc(sizeof * sp);
- //lua_pushinteger(dest, 55);
int r = luaL_ref(dest, LUA_REGISTRYINDEX);
lua_rawgeti(dest, LUA_REGISTRYINDEX, r);
*sp = r;
parray_set(seen, aauwu, sp);
- //printf("saved %i\n", *sp);
- //for(int i = 0; i != seen->len; i++){
- // printf("%i ", *(int*)seen->P[i].value);
- //}
lua_pushnil(src);
for(;lua_next(src, at2) != 0;){
- lua_pushvalue(src, -2);
- int a = lua_gettop(src);
- //l_pprint(src);
- lua_settop(src, a);
- i_dcopy(src, dest, seen);
-
- lua_pushvalue(src, -2);
- i_dcopy(src, dest, seen);
-
+ int first, second = first = lua_gettop(src);
+ first -= 1;
+ lua_pushvalue(src, first);
+ luaI_deepcopy(src, dest, seen, 0);
+
+ lua_pushvalue(src, second);
+ luaI_deepcopy(src, dest, seen, 0);
lua_settable(dest, at);
+
lua_pop(src, 3);
}
- //printf("done\n");
- //lua_settop(dest, at);
break;
case LUA_TFUNCTION:
- if(lua_iscfunction(src, old_top)){
- //kinda silly
- lua_pushcfunction(dest, lua_tocfunction(src, -1));
- break;
- }
+ if(lua_iscfunction(src, old_top)){
+ //kinda silly
+ lua_pushcfunction(dest, lua_tocfunction(src, -1));
+ break;
+ }
- str* awa = str_init("");
- lua_dump(src, writer, (void*)awa, 0);
- lua_pushlstring(dest, awa->c, awa->len);
+ str* awa = str_init("");
+ lua_dump(src, writer, (void*)awa, 0);
+ lua_pushlstring(dest, awa->c, awa->len);
- luaL_loadbuffer(dest, awa->c, awa->len, awa->c);
- lua_remove(dest, -2);
- str_free(awa);
- //lua_pushvalue(dest, -1);
- break;
+ luaL_loadbuffer(dest, awa->c, awa->len, awa->c);
+ lua_remove(dest, -2);
+ str_free(awa);
+ break;
case LUA_TUSERDATA:
+ modi = 1;
+ size_t raw_len = lua_rawlen(src, -1);
+ void* ud = lua_newuserdata(dest, raw_len);
+ memcpy(ud, lua_touserdata(src, -1), raw_len);
+ break;
case LUA_TLIGHTUSERDATA:
- lua_pushlightuserdata(dest, lua_touserdata(src, -1));
- int tidx = lua_gettop(dest);
-
- if(lua_getmetatable(src, -1)){
- //int a = lua_gettop(src);
- //l_pprint(src);
- //lua_settop(src, a);
- //printf("**--**\n");
- i_dcopy(src, dest, seen);
- //int a = lua_gettop(dest);
- //l_pprint(dest);
- //lua_settop(dest, a);
- lua_setmetatable(dest, tidx);
- lua_pop(src, 1);
- }
- lua_settop(dest, tidx);
- //printf("aww\n");
- //lua_pushnumber(dest, 8);
- break;
+ modi = 1;
+ lua_pushlightuserdata(dest, lua_touserdata(src, -1));
+ break;
default:
- printf("%i\n",lua_type(src, -1));
- lua_pushnil(dest);
- break;
+ printf("unknown type %i\n",lua_type(src, -1));
+ lua_pushnil(dest);
+ break;
}
+ int tidx = lua_gettop(dest);
+ int aa = lua_gettop(src);
+
+ if(modi&&!skip_meta&&lua_getmetatable(src, -1)){
+ luaI_deepcopy(src, dest, seen, 1);
+ lua_setmetatable(dest, tidx);
+
+ lua_settop(dest, tidx);
+ }
+ lua_settop(src, aa);
+
if(wnull) parray_clear(seen, FREE);
- //lua_settop(src, old_top);
_seen = seen;
}
@@ -6,7 +6,7 @@ void* __malloc_(size_t);
void __free_(void*);
-void i_dcopy(lua_State* src, lua_State* dest, void*);
+void luaI_deepcopy(lua_State* src, lua_State* dest, void* _seen, int);
void lua_set_global_table(lua_State*);
//generic macro that takes other macros (see below)
@@ -754,7 +754,7 @@ void* handle_client(void *_arg){ lua_getglobal(args->L, "_G");
//time_start(copy)
- i_dcopy(args->L, L, NULL);
+ luaI_deepcopy(args->L, L, NULL, 0);
//time_end("copy", copy)
lua_settop(args->L, old_top);
diff --git a/src/thread.c b/src/thread.c index dd4052a..dec9ceb 100644 --- a/src/thread.c +++ b/src/thread.c @@ -9,6 +9,7 @@ #include "util.h"
#include "types/larray.h"
+#include "hash/fnv.h"
struct thread_info {
str* function;
@@ -96,7 +97,7 @@ int l_res(lua_State* L){ int ot = lua_gettop(L);
lua_pushvalue(L, 2 + i);
- i_dcopy(L, info->L, NULL);
+ luaI_deepcopy(L, info->L, NULL, 0);
lua_settop(L, ot);
}
@@ -148,7 +149,7 @@ int l_await(lua_State* L){ int ot = lua_gettop(info->L);
lua_pushvalue(info->L, ot - info->return_count + i);
- i_dcopy(info->L, L, NULL);
+ luaI_deepcopy(info->L, L, NULL, 0);
lua_settop(info->L, ot);
}
@@ -177,10 +178,10 @@ int l_clean(lua_State* L){ int l_async(lua_State* oL){
lua_State* L = luaL_newstate();
- luaL_openlibs(L);
+ //luaL_openlibs(L);
lua_getglobal(oL, "_G");
- i_dcopy(oL, L, NULL);
+ luaI_deepcopy(oL, L, NULL, 0);
lua_set_global_table(L);
struct thread_info* args = calloc(1, sizeof * args);
@@ -211,3 +212,91 @@ int l_async(lua_State* oL){ lua_pushvalue(oL, res_idx);
return 1;
}
+
+struct thread_buffer {
+ lua_State* L;
+ pthread_mutex_t lock;
+};
+
+int _buffer_get(lua_State* L){
+ struct thread_buffer *buffer = lua_touserdata(L, 1);
+ pthread_mutex_lock(&buffer->lock);
+ luaI_deepcopy(buffer->L, L, NULL, 0);
+ pthread_mutex_unlock(&buffer->lock);
+ return 1;
+}
+
+int _buffer_set(lua_State* L){
+ struct thread_buffer *buffer = lua_touserdata(L, 1);
+ pthread_mutex_lock(&buffer->lock);
+ lua_settop(buffer->L, 0);
+ luaI_deepcopy(L, buffer->L, NULL, 0);
+ pthread_mutex_unlock(&buffer->lock);
+ return 1;
+}
+
+int _buffer_mod(lua_State* L){
+ struct thread_buffer *buffer = lua_touserdata(L, 1);
+ pthread_mutex_lock(&buffer->lock);
+ luaI_deepcopy(buffer->L, L, NULL, 0);
+ int item = lua_gettop(L);
+ lua_pushvalue(L, 2);
+ lua_pushvalue(L, item);
+ lua_call(L, 1, 1);
+
+ if(lua_type(L, -1) != LUA_TNIL){
+ lua_settop(buffer->L, 0);
+ luaI_deepcopy(L, buffer->L, NULL, 0);
+ }
+ pthread_mutex_unlock(&buffer->lock);
+ return 1;
+}
+
+
+int l_buffer_index(lua_State* L){
+ uint64_t len, hash;
+ const char* str = luaL_tolstring(L, 2, &len);
+
+ hash = fnv_1((uint8_t*)str, len, v_1);
+
+ switch(hash){
+ case 0xd8c8ad186b9ed323: //get
+ lua_pushcfunction(L, _buffer_get);
+ break;
+ case 0xd89f9d186b7bb367: //set
+ lua_pushcfunction(L, _buffer_set);
+ break;
+ case 0xd8b3c7186b8ca31f: //mod
+ lua_pushcfunction(L, _buffer_mod);
+ break;
+ default:
+ lua_pushnil(L);
+ break;
+ }
+ return 1;
+}
+
+int l_buffer(lua_State* L){
+ struct thread_buffer *buffer = malloc(sizeof * buffer);
+ buffer->L = luaL_newstate();
+ pthread_mutex_init(&buffer->lock, NULL);
+ luaI_deepcopy(L, buffer->L, NULL, 0);
+
+ lua_newtable(L);
+ int meta_idx = lua_gettop(L);
+ luaI_tsetcf(L, meta_idx, "__index", l_buffer_index);
+
+ lua_pushlightuserdata(L, buffer);
+ lua_pushvalue(L, meta_idx);
+ lua_setmetatable(L, -2);
+
+ return 1;
+}
+
+int l_testcopy(lua_State* L){
+ lua_State* temp = luaL_newstate();
+ luaI_deepcopy(L, temp, NULL, 0);
+ luaI_deepcopy(temp, L, NULL, 0);
+
+ return 1;
+}
diff --git a/src/thread.h b/src/thread.h index 9dab9b1..b83db4c 100644 --- a/src/thread.h +++ b/src/thread.h @@ -3,6 +3,8 @@ int l_async(lua_State*);
int l_tlock(lua_State*);
int l_tunlock(lua_State*);
+int l_buffer(lua_State*);
+int l_testcopy(lua_State*);
void lib_thread_clean();
@@ -10,5 +12,7 @@ static const luaL_Reg thread_function_list [] = { {"async",l_async},
{"lock",l_tlock},
{"unlock",l_tunlock},
+ {"buffer",l_buffer},
+ {"testcopy",l_testcopy},
{NULL,NULL}
};
diff --git a/tests/h.lua b/tests/h.lua index ca946fc..412d09c 100644 --- a/tests/h.lua +++ b/tests/h.lua @@ -1,32 +1,29 @@ require "llib"
+llib.config.set({print_meta=1,max_depth=22})
--llib.thread.lock(1)
--llib.thread.lock(2)
--llib.thread.unlock(2)
+a = llib.thread.buffer(llib.crypto.md5())
-local thread_a = llib.thread.async(function (res)
- --os.execute("sleep 1")
- --print((_G.ll + "hi"):final())
- print("waiting..")
- --llib.thread.lock(1)
- _G.test = 5
- print("signal!")
- res(llib.thread.async(function (res)
- print(test)
- res(test)
- end))
- print("after")
-end)
+a:mod(function(e) return e end)
+print("hi")
+for i=1,20 do
+ llib.thread.async(function (res)
+ a:mod(function(e) return e:update("meow") end)
+ end)
+end
---os.execute("sleep 1")
+os.execute("sleep 1")
+print(a:get():final())
--print("unlock")
--llib.thread.unlock(1)
-awa = thread_a:await()
+--awa = thread_a:await()
-print(awa:await())
+--print(awa:await())
--print((awa + "hi"):final())
-thread_a:clean()
+--thread_a:clean()
print("clean exit")
diff --git a/tests/net.lua b/tests/net.lua index 228a29b..88b551e 100644 --- a/tests/net.lua +++ b/tests/net.lua @@ -12,7 +12,7 @@ local wowa = 5 _G._llib = _G.llib
--_G.ww = llib
--llib.io.pprint(_G)
-
+a = llib.crypto.md5
llib.net.listen(
function(server)
--llib = nil
@@ -20,6 +20,10 @@ llib.net.listen( llib.io.pprint("online")
_G.server = server
server:all("/", function(res, req)
+ b = a("hello")
+
+ --llib.io.pprint(a + '5')
+ res:send(b)
--llib.io.pprint(res)
--llib.io.pprint(res)
--print(res.send)
@@ -57,7 +61,7 @@ llib.net.listen( --_G.llib.io.pprint(req.files)
--_G.llib.io.pprint(req)
--_G.llib.io.pprint("hi")
- res:send("done")
+ --res:send("done")
end)
server:GET("/aa", function(res, req)
|
