/* * Call a function ('func_name') in the keeper state, and pass on the returned * values to 'L'. * * 'linda': deep Linda pointer (used only as a unique table key, first parameter) * 'starting_index': first of the rest of parameters (none if 0) * * Returns: number of return values (pushed to 'L') or -1 in case of error */ int keeper_call( lua_State *K, keeper_api_t _func, lua_State *L, void *linda, uint_t starting_index) { int const args = starting_index ? (lua_gettop( L) - starting_index + 1) : 0; int const Ktos = lua_gettop( K); int retvals = -1; STACK_GROW( K, 2); PUSH_KEEPER_FUNC( K, _func); lua_pushlightuserdata( K, linda); if( (args == 0) || luaG_inter_copy( L, K, args, eLM_ToKeeper) == 0) // L->K { lua_call( K, 1 + args, LUA_MULTRET); retvals = lua_gettop( K) - Ktos; // note that this can raise a luaL_error while the keeper state (and its mutex) is acquired // this may interrupt a lane, causing the destruction of the underlying OS thread // after this, another lane making use of this keeper can get an error code from the mutex-locking function // when attempting to grab the mutex again (WINVER <= 0x400 does this, but locks just fine, I don't know about pthread) if( (retvals > 0) && luaG_inter_move( K, L, retvals, eLM_FromKeeper) != 0) // K->L { retvals = -1; } } // whatever happens, restore the stack to where it was at the origin lua_settop( K, Ktos); return retvals; }
/* * Call a function ('func_name') in the keeper state, and pass on the returned * values to 'L'. * * 'linda': deep Linda pointer (used only as a unique table key, first parameter) * 'starting_index': first of the rest of parameters (none if 0) * * Returns: number of return values (pushed to 'L') or -1 in case of error */ int keeper_call( lua_State *K, keeper_api_t _func, lua_State *L, void *linda, uint_t starting_index) { int const args = starting_index ? (lua_gettop( L) - starting_index + 1) : 0; int const Ktos = lua_gettop( K); int retvals = -1; STACK_GROW( K, 2); PUSH_KEEPER_FUNC( K, _func); lua_pushlightuserdata( K, linda); if( (args == 0) || luaG_inter_copy( L, K, args) == 0) // L->K { lua_call( K, 1 + args, LUA_MULTRET); retvals = lua_gettop( K) - Ktos; if( (retvals > 0) && luaG_inter_move( K, L, retvals) != 0) // K->L { retvals = -1; } } // whatever happens, restore the stack to where it was at the origin lua_settop( K, Ktos); return retvals; }