Skip to content

Commit

Permalink
fix reentrant case of luantik_run
Browse files Browse the repository at this point in the history
  • Loading branch information
lneto committed Nov 22, 2023
1 parent ebee301 commit ce2dbe1
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 20 deletions.
13 changes: 9 additions & 4 deletions lib/luanotifier.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,13 @@ static int luanotifier_call(struct notifier_block *nb, unsigned long event, void
luanotifier_t *notifier = container_of(nb, luanotifier_t, nb);
int ret;

notifier->running = true;
lunatik_run(notifier->runtime, luanotifier_handler, ret, notifier, event, data);
notifier->running = false;
if (notifier->running)
lunatik_handle(notifier->runtime, luanotifier_handler, ret, notifier, event, data);
else {
notifier->running = true;
lunatik_run(notifier->runtime, luanotifier_handler, ret, notifier, event, data);
notifier->running = false;
}
return ret;
}

Expand All @@ -109,7 +113,6 @@ static int luanotifier_new(lua_State *L, luanotifier_register_t register_fn, lua
notifier = (luanotifier_t *)lua_newuserdatauv(L, sizeof(luanotifier_t), 1);
notifier->runtime = lunatik_toruntime(L);
notifier->nb.notifier_call = luanotifier_call;
notifier->running = false;
notifier->unregister = unregister_fn;
notifier->handler = handler_fn;

Expand All @@ -119,8 +122,10 @@ static int luanotifier_new(lua_State *L, luanotifier_register_t register_fn, lua
lua_pushvalue(L, -1); /* push userdata */
notifier->ud = luaL_ref(L, LUA_REGISTRYINDEX); /* pops userdata */

notifier->running = true; /* notifier_call might be called directly (e.g., NETDEV_REGISTER) */
if (register_fn(&notifier->nb) != 0)
luaL_error(L, "couldn't create notifier");
notifier->running = false;

luaL_setmetatable(L, LUANOTIFIER_MT);
return 1; /* userdata */
Expand Down
31 changes: 15 additions & 16 deletions lunatik.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,23 +82,22 @@ static inline void lunatik_release(struct kref *kref)

#define lunatik_cansleep(L) (!lunatik_getready(L) || lunatik_getsleep(L))

#define lunatik_run(runtime, handler, ret, ...) \
#define lunatik_handle(runtime, handler, ret, ...) \
do { \
lua_State *L; \
int unlocked = !lunatik_islocked(runtime); \
if (likely(unlocked)) \
lunatik_lock(runtime); \
L = runtime->L; \
if (unlikely(!L)) \
ret = -ENXIO; \
else { \
int n; \
n = lua_gettop(L); \
ret = handler(L, ## __VA_ARGS__); \
lua_settop(L, n); \
} \
if (likely(unlocked)) \
lunatik_unlock(runtime); \
lua_State *L = runtime->L; \
int n = lua_gettop(L); \
ret = handler(L, ## __VA_ARGS__); \
lua_settop(L, n); \
} while(0)

#define lunatik_run(runtime, handler, ret, ...) \
do { \
lunatik_lock(runtime); \
if (unlikely(!runtime->L)) \
ret = -ENXIO; \
else \
lunatik_handle(runtime, handler, ret, ## __VA_ARGS__); \
lunatik_unlock(runtime); \
} while(0)

typedef struct lunatik_reg_s {
Expand Down

0 comments on commit ce2dbe1

Please sign in to comment.