> The test code holds the created threads by inserting them in a table:
>
>
> function should.not_segfault()
> local threads = {}
> local functions = {}
> collectgarbage('stop')
> for i = 1,100 do
> table.insert(threads, rk.Thread(function()
> -- do nothing
> local j = 0
> while j < 10 do
> print(i, j)
> j = j + 1
> worker:sleep(20)
> end
> end))
> if i == 60 then
> collectgarbage('collect')
> print("collect ok.")
> end
> end
>
> for _, thread in ipairs(threads) do
> thread:join()
> end
>
> -- should not hang
> assert_true(true)
> end
>
> Any idea what I am doing wrong ?
>
> Gaspard (6am here: going to bed)
>
> On Mon, Jan 3, 2011 at 3:40 AM, Gaspard Bucher <
gaspard@teti.ch> wrote:
> > Storing the function in the environment table is one thing, but getting
> > it back from C is another...
> >
> > In order to get back to the function, I figured out this pattern:
> >
> > 0. On startup: create a weak table in the registry and store the location
> > as a C global
> >
> > 1. push the weak table on top
> > lua_rawgeti(L, LUA_REGISTRYINDEX, g_weak_table_idx);
> >
> > 2. create reference
> > lua_pushvalue(L, -2);
> > int func_idx = luaL_ref(L, -1);
> >
> > .. later ..
> > 3. push weak table on top and get function
> > lua_rawgeti(L, LUA_REGISTRYINDEX, g_weak_table_idx);
> > lua_rawgeti(L, -1, func_idx);
> >
> > Does this look ok ?
> >
> > G.
> >
> > On Mon, Jan 3, 2011 at 3:01 AM, Gaspard Bucher <
gaspard@teti.ch> wrote:
> >> Hi Peter,
> >>
> >> Thanks, this seems to be the correct way to handle my issue. I am
> >> looking at lua_getfenv and lua_setfenv and am not sure if this is how it
> >> is meant to be used:
> >>
> >> -- callback function is at 1
> >> -- rk.Thread userdata is at 2
> >> lua_getfenv(L, 2);
> >> lua_pushvalue(L, 1);
> >> lua_pushstring(L, "callback");
> >> lua_settable(L, -3);
> >>
> >> G.
> >>
> >> On Mon, Jan 3, 2011 at 2:03 AM, Peter Odding
<
peter@peterodding.com>wrote:
> >>> Hi Gaspard,
> >>>
> >>>
> >>> This is a difficult one: I have an OS thread that keeps hold of a
> >>>
> >>>> function in lua with luaL_ref(L, LUA_REGISTRYINDEX). But the OS thread
> >>>> is created in Lua:
> >>>>
> >>>> thread = rk.Thread(function()
> >>>> -- do this and that
> >>>> end
> >>>>
> >>>> After some time, the thread is garbage collected.
> >>>>
> >>>> How can I remove the function from the registry ? I cannot call
> >>>> luaL_unref in the rk.Thread destructor (segfault).
> >>>
> >>> I'm not sure I have the full picture here, but why not give your thread
> >>> userdata an environment table and then keep hold of the function in
> >>> that environment table instead of in the global registry? Once your
> >>> thread is garbage collected the environment table should be destroyed
> >>> and any references in that table should automatically seize to exist.
> >>>
> >>> - Peter Odding