lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Sat, May 9, 2015 at 9:27 AM, Dibyendu Majumdar
<mobile@majumdar.org.uk> wrote:
> The core Lua api functions have a lua_lock() / lua_unlock() call
> bracketing each api function. The default implementation does nothing
> but I presume these stubs are for users who wish to ensure that the
> same Lua state can be used by multiple OS threads.
>
> I have noticed that the way these calls are implemented they will not
> work reliably. For instance:
>
> LUA_API void lua_settable (lua_State *L, int idx) {
>   StkId t;
>   lua_lock(L);
>   api_checknelems(L, 2);
>   t = index2addr(L, idx);
>   luaV_settable(L, t, L->top - 2, L->top - 1);
>   L->top -= 2;  /* pop index and value */
>   lua_unlock(L);
> }
>
> If luaV_settable() threw an exception (i.e. performed a longjmp) then
> the lua_unlock() will never be called. Is this a correct assessment or
> am I missing something?
>
> If above is true then the only way this would work was if Lua was
> compiled in C++, the throw implementation was switched to C++
> exception handling, and the locks were implemented with appropriate
> auto destruction semantics.
>

You don't need C++ for this.

1. A mutex must be recursive [1], i.e. an owning thread can lock it
again without being self-blocked. unlock() must be called once for
each level of ownership acquired by a single thread before ownership
can be acquired by another thread.

2. If an API function throws, then it must be called in protected mode
to prevent Lua panic. Function lua_pcall locks the mutex (ownership
level = 1), then called lua_settable locks already locked mutex
(ownership level = 2), after which throws Lua exception (longjmp).

3. In case of error, lua_pcall sets mutex's ownership level to the
value it had before protected call (in this case, ownership level =
1).

[1] http://www.boost.org/doc/libs/1_41_0/doc/html/thread/synchronization.html#thread.synchronization.mutex_types.recursive_mutex

-- 


Best regards,
Boris Nagaev