/* * Initialize keeper states * * If there is a problem, return an error message (NULL for okay). * * Note: Any problems would be design flaws; the created Lua state is left * unclosed, because it does not really matter. In production code, this * function never fails. */ char const* init_keepers( int const _nbKeepers, lua_CFunction _on_state_create) { int i; assert( _nbKeepers >= 1); GNbKeepers = _nbKeepers; GKeepers = malloc( _nbKeepers * sizeof( struct s_Keeper)); for( i = 0; i < _nbKeepers; ++ i) { // We need to load all base libraries in the keeper states so that the transfer databases are populated properly // // 'io' for debugging messages, 'package' because we need to require modules exporting idfuncs // the others because they export functions that we may store in a keeper for transfer between lanes lua_State* K = luaG_newstate( "*", _on_state_create); if (!K) return "out of memory"; STACK_CHECK( K) // to see VM name in Decoda debugger lua_pushliteral( K, "Keeper #"); lua_pushinteger( K, i + 1); lua_concat( K, 2); lua_setglobal( K, "decoda_name"); #if KEEPER_MODEL == KEEPER_MODEL_C // create the fifos table in the keeper state lua_pushlightuserdata( K, fifos_key); lua_newtable( K); lua_rawset( K, LUA_REGISTRYINDEX); #endif // KEEPER_MODEL == KEEPER_MODEL_C #if KEEPER_MODEL == KEEPER_MODEL_LUA // use package.loaders[2] to find keeper microcode lua_getglobal( K, "package"); // package lua_getfield( K, -1, "loaders"); // package package.loaders lua_rawgeti( K, -1, 2); // package package.loaders package.loaders[2] lua_pushliteral( K, "lanes-keeper"); // package package.loaders package.loaders[2] "lanes-keeper" STACK_MID( K, 4); // first pcall loads lanes-keeper.lua, second one runs the chunk if( lua_pcall( K, 1 /*args*/, 1 /*results*/, 0 /*errfunc*/) || lua_pcall( K, 0 /*args*/, 0 /*results*/, 0 /*errfunc*/)) { // LUA_ERRRUN / LUA_ERRMEM / LUA_ERRERR // char const* err = lua_tostring( K, -1); assert( err); return err; } // package package.loaders STACK_MID( K, 2); lua_pop( K, 2); #endif // KEEPER_MODEL == KEEPER_MODEL_LUA STACK_END( K, 0) MUTEX_INIT( &GKeepers[i].lock_); GKeepers[i].L = K; //GKeepers[i].count = 0; } #if HAVE_KEEPER_ATEXIT_DESINIT atexit( atexit_close_keepers); #endif // HAVE_KEEPER_ATEXIT_DESINIT return NULL; // ok }
/* * Initialize keeper states * * If there is a problem, return an error message (NULL for okay). * * Note: Any problems would be design flaws; the created Lua state is left * unclosed, because it does not really matter. In production code, this * function never fails. */ char const* init_keepers( lua_State* L, int _on_state_create, int const _nbKeepers) { int i; assert( _nbKeepers >= 1); GNbKeepers = _nbKeepers; GKeepers = malloc( _nbKeepers * sizeof( struct s_Keeper)); for( i = 0; i < _nbKeepers; ++ i) { lua_State* K; DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "### init_keepers %d BEGIN\n" INDENT_END, i)); DEBUGSPEW_CODE( ++ debugspew_indent_depth); // We need to load all base libraries in the keeper states so that the transfer databases are populated properly // // 'io' for debugging messages, 'package' because we need to require modules exporting idfuncs // the others because they export functions that we may store in a keeper for transfer between lanes K = luaG_newstate( L, _on_state_create, "K"); STACK_CHECK( K); // replace default 'package' contents with stuff gotten from the master state lua_getglobal( L, "package"); luaG_inter_copy_package( L, K, -1); lua_pop( L, 1); DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "### init_keepers %d END\n" INDENT_END, i)); DEBUGSPEW_CODE( -- debugspew_indent_depth); // to see VM name in Decoda debugger lua_pushliteral( K, "Keeper #"); lua_pushinteger( K, i + 1); lua_concat( K, 2); lua_setglobal( K, "decoda_name"); #if KEEPER_MODEL == KEEPER_MODEL_C // create the fifos table in the keeper state lua_pushlightuserdata( K, fifos_key); lua_newtable( K); lua_rawset( K, LUA_REGISTRYINDEX); #endif // KEEPER_MODEL == KEEPER_MODEL_C #if KEEPER_MODEL == KEEPER_MODEL_LUA // use package.loaders[2] to find keeper microcode (NOTE: this works only if nobody tampered with the loaders table...) lua_getglobal( K, "package"); // package lua_getfield( K, -1, "loaders"); // package package.loaders lua_rawgeti( K, -1, 2); // package package.loaders package.loaders[2] lua_pushliteral( K, "lanes-keeper"); // package package.loaders package.loaders[2] "lanes-keeper" STACK_MID( K, 4); // first pcall loads lanes-keeper.lua, second one runs the chunk if( lua_pcall( K, 1 /*args*/, 1 /*results*/, 0 /*errfunc*/) || lua_pcall( K, 0 /*args*/, 0 /*results*/, 0 /*errfunc*/)) { // LUA_ERRRUN / LUA_ERRMEM / LUA_ERRERR // char const* err = lua_tostring( K, -1); assert( err); return err; } // package package.loaders STACK_MID( K, 2); lua_pop( K, 2); #endif // KEEPER_MODEL == KEEPER_MODEL_LUA STACK_END( K, 0); MUTEX_INIT( &GKeepers[i].lock_); GKeepers[i].L = K; //GKeepers[i].count = 0; } #if HAVE_KEEPER_ATEXIT_DESINIT atexit( atexit_close_keepers); #endif // HAVE_KEEPER_ATEXIT_DESINIT return NULL; // ok }