fix(dirmonitor): deadlock if error handler jumps somewhere else (#1647)

* fix: deadlock if error handler jumps somewhere else

* docs(dirmonitor): fix wrong data type in error callback

* docs(dirmonitor): clarify coroutines and deadlocks

* docs(dirmonitor): wording

Co-authored-by: Guldoman <giulio.lettieri@gmail.com>

---------

Co-authored-by: Guldoman <giulio.lettieri@gmail.com>
This commit is contained in:
Takase
2023-10-24 20:16:52 +08:00
committed by takase1121
co-authored by Guldoman
parent 4005a46144
commit 5d53b13cf4
3 changed files with 28 additions and 4 deletions
+19 -3
View File
@@ -1,4 +1,5 @@
#include "api.h"
#include "lua.h"
#include <SDL.h>
#include <stdlib.h>
#include <string.h>
@@ -25,13 +26,16 @@ int get_mode_dirmonitor();
static int f_check_dir_callback(int watch_id, const char* path, void* L) {
lua_pushvalue(L, -1);
// using absolute indices from f_dirmonitor_check (2: callback, 3: error_callback)
lua_pushvalue(L, 2);
if (path)
lua_pushlstring(L, path, watch_id);
else
lua_pushnumber(L, watch_id);
lua_call(L, 1, 1);
int result = lua_toboolean(L, -1);
int result = 0;
if (lua_pcall(L, 1, 1, 3) == LUA_OK)
result = lua_toboolean(L, -1);
lua_pop(L, 1);
return !result;
}
@@ -95,8 +99,20 @@ static int f_dirmonitor_unwatch(lua_State *L) {
}
static int f_noop(lua_State *L) { return 0; }
static int f_dirmonitor_check(lua_State* L) {
struct dirmonitor* monitor = luaL_checkudata(L, 1, API_TYPE_DIRMONITOR);
luaL_checktype(L, 2, LUA_TFUNCTION);
if (!lua_isnoneornil(L, 3)) {
luaL_checktype(L, 3, LUA_TFUNCTION);
} else {
lua_settop(L, 2);
lua_pushcfunction(L, f_noop);
}
lua_settop(L, 3);
SDL_LockMutex(monitor->mutex);
if (monitor->length < 0)
lua_pushnil(L);