Esempio n. 1
0
int keeper_push_linda_storage( struct s_Universe* U, lua_State* L, void* ptr, unsigned long magic_)
{
	struct s_Keeper* K = keeper_acquire( U->keepers, magic_);
	lua_State* KL = K ? K->L : NULL;
	if( KL == NULL) return 0;
	STACK_GROW( KL, 4);
	STACK_CHECK( KL);
	lua_pushlightuserdata( KL, fifos_key);                      // fifos_key
	lua_rawget( KL, LUA_REGISTRYINDEX);                         // fifos
	lua_pushlightuserdata( KL, ptr);                            // fifos ud
	lua_rawget( KL, -2);                                        // fifos storage
	lua_remove( KL, -2);                                        // storage
	if( !lua_istable( KL, -1))
	{
		lua_pop( KL, 1);                                          //
		STACK_MID( KL, 0);
		return 0;
	}
	// move data from keeper to destination state                  KEEPER                       MAIN
	lua_pushnil( KL);                                           // storage nil
	STACK_GROW( L, 5);
	STACK_CHECK( L);
	lua_newtable( L);                                                                        // out
	while( lua_next( KL, -2))                                   // storage key fifo
	{
		keeper_fifo* fifo = prepare_fifo_access( KL, -1);         // storage key fifo
		lua_pushvalue( KL, -2);                                   // storage key fifo key
		luaG_inter_move( U, KL, L, 1, eLM_FromKeeper);            // storage key fifo          // out key
		STACK_MID( L, 2);
		lua_newtable( L);                                                                      // out key keyout
		luaG_inter_move( U, KL, L, 1, eLM_FromKeeper);            // storage key               // out key keyout fifo
		lua_pushinteger( L, fifo->first);                                                      // out key keyout fifo first
		STACK_MID( L, 5);
		lua_setfield( L, -3, "first");                                                         // out key keyout fifo
		lua_pushinteger( L, fifo->count);                                                      // out key keyout fifo count
		STACK_MID( L, 5);
		lua_setfield( L, -3, "count");                                                         // out key keyout fifo
		lua_pushinteger( L, fifo->limit);                                                      // out key keyout fifo limit
		STACK_MID( L, 5);
		lua_setfield( L, -3, "limit");                                                         // out key keyout fifo
		lua_setfield( L, -2, "fifo");                                                          // out key keyout
		lua_rawset( L, -3);                                                                    // out
		STACK_MID( L, 1);
	}
	STACK_END( L, 1);
	lua_pop( KL, 1);                                            //
	STACK_END( KL, 0);
	keeper_release( K);
	return 1;
}
Esempio n. 2
0
/*
* 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;
}
Esempio n. 3
0
/*
* 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;
}
Esempio n. 4
0
int keeper_push_linda_storage( lua_State* L, void* ptr)
{
	struct s_Keeper* K = keeper_acquire( ptr);
	lua_State* KL = K->L;
	STACK_CHECK( KL)
	lua_pushlightuserdata( KL, fifos_key);                      // fifos_key
	lua_rawget( KL, LUA_REGISTRYINDEX);                         // fifos
	lua_pushlightuserdata( KL, ptr);                            // fifos ud
	lua_rawget( KL, -2);                                        // fifos storage
	lua_remove( KL, -2);                                        // storage
	if( !lua_istable( KL, -1))
	{
		lua_pop( KL, 1);                                          //
		STACK_MID( KL, 0);
		return 0;
	}
	lua_pushnil( KL);                                           // storage nil
	lua_newtable( L);                                                                        // out
	while( lua_next( KL, -2))                                   // storage key fifo
	{
		keeper_fifo* fifo = prepare_fifo_access( KL, -1);         // storage key fifo
		lua_pushvalue( KL, -2);                                   // storage key fifo key
		luaG_inter_move( KL, L, 1);                               // storage key fifo          // out key
		STACK_CHECK( L)
		lua_newtable( L);                                                                      // out key keyout
		luaG_inter_move( KL, L, 1);                               // storage key               // out key keyout fifo
		lua_pushinteger( L, fifo->first);                                                      // out key keyout fifo first
		lua_setfield( L, -3, "first");                                                         // out key keyout fifo
		lua_pushinteger( L, fifo->count);                                                      // out key keyout fifo count
		lua_setfield( L, -3, "count");                                                         // out key keyout fifo
		lua_pushinteger( L, fifo->limit);                                                      // out key keyout fifo limit
		lua_setfield( L, -3, "limit");                                                         // out key keyout fifo
		lua_setfield( L, -2, "fifo");                                                          // out key keyout
		lua_rawset( L, -3);                                                                    // out
		STACK_END( L, 0)
	}
	lua_pop( KL, 1);                                            //
	STACK_END( KL, 0)
	keeper_release( K);
	return 1;
}