LuaLanes / lanes

Lanes is a lightweight, native, lazy evaluating multithreading library for Lua 5.1 to 5.4.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Transfering global C functions to lanes

deorder opened this issue · comments

I am using Lua lanes embedded in my host application. The only way to get the globals (_G) transfered to a lane is by filtering out the C functions:

...

local lanes = require "lanes".configure{
  nb_keepers = 1,
  with_timers = false,
  on_state_create = test_on_state_create
}

...

local function globals_get()
  local globals = {}
  for k, v in pairs(_G) do
    if type(v) == "function" then
      local info = debug.getinfo(v, 'S')
      if info.what == "Lua" then
        globals[k] = v
      end
    else
      globals[k] = v
    end
  end
  return globals
end

local function job_schedule(scheduled_jobs, func, ...)
  scheduled_jobs[#scheduled_jobs + 1] = {
    -- Using globals_get() to filter out the C functions from _G
    func = lanes.gen("*", {globals = globals_get()}, function(...)
      return func(...)
    end),
    args = {...}
  }
  return EXIT_SUCCESS
end

...

This works in Lua5.x and Luajit. If I do not filter out the C functions I get errors like:

Lane #0x557803c82600: function 'set_finalizer' not found in Lane #0x7fad800175d0 destination transfer database.

This is not limited to set_finalizer, sometimes it complains about other C functions including my custom C functions I registered in the host application as follows:

...

static const luaL_reg test_functions[] = {
  {"test_func_a", test_func_a},
  {"test_func_b", test_func_b},
  {NULL, NULL}
};

int luaopen_test(lua_State *lua_state) {
  lua_newtable(lua_state);
  xlua_setfuncs(lua_state, test_functions, 0);
  return 1;
}

static int test_on_state_create(lua_State* lua_state) {
  luaopen_test(lua_state);
  lua_setglobal(lua_state, "test");
  lua_pushcfunction(lua_state, test_on_state_create);
  lua_setglobal(lua_state, "test_on_state_create");  
  return 0;
}

int load_lanes_lua(lua_State* lua_state) {
  if(luaL_dostring(lua_state, lanes_lua)) {
    fprintf(stderr, "error in lua file: '%s'\n", lua_tostring(lua_state, -1));
    lua_close(lua_state);
    exit(EXIT_FAILURE);
  }
  return 1;
}

...

luaL_openlibs(lua_state);

luaopen_lanes_embedded(lua_state, load_lanes_lua);
lua_pop(lua_state, 1);

test_on_state_create(lua_state);

...

Is there a better way to get this to work instead of copying all _G entries and filtering out the C functions myself?

Have you tried lanes.register("name", func)? I think you can thus register the global C functions in the master state, then in each lane's on_state_create.