[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Thread in library which call Lua function
- From: "Robert G. Jakabosky" <bobby@...>
- Date: Fri, 15 Apr 2011 21:35:51 -0700
On Friday 15, jseb wrote:
> Hello,
>
> I've got a thread started inside a library. This thread calls a Lua
> function from the Lua script which required this library.
> Between each loop, the thread is waiting one second
The standard Lua interpreter is not re-entrance safe. You will have to build
a custom interpreter which uses locks to only allow one thread to access the
lua_State object at a time.
I wouldn't recommend doing this anyways since it will not scale. It would be
better to use one lua_State per thread and use message passing for
communication between the threads.
> I've encounters random hangs while running it:
>
> - segfault as soon as the Lua script is launched.
> - one second wait, then segfault.
> - never return, nor show anything (manual termination with ctrl+c)
> - sometimes, some cryptic curses from Lua interpreter, like:
>
> lua: attempt to concatenate a nil valueattempt to call a nil value
> stack traceback:
> [C]: in function 'clock'
> ./test_libfoo.lua:14: in main chunk
> [C]: ?
>
> (line 14 is: while os.clock() - timer <= 5 do end )
>
> The funny thing is it seems that it is my temporisation which disturb Lua:
> timer = os.clock()
> while os.clock() - timer <= 5 do end
>
>
> Worse, an "old school temporisation" works;
> for i=0,300000000 do end
>
>
> I know the problem is not my temporisation, as the first version (with
> "os.clock()" ) is working in a standalone script.
>
> I think i have a serious problem here, and i'm not waiting for you for
> debugging my experiments. Which annoys me is that i was trying to write
> a short program for isolating another problem i encounter with
> re-entrance in Lua :(
> So, i'm opened to all suggestions for solving the drifting problem.
>
> Thank you.
>
>
> Here is the complete Lua script:
>
> #!/usr/bin/env lua
>
> foo = require ("libfoo")
>
> function lua_callback()
> print ("I am the function located in Lua script")
> end
>
> foo:set_callback (lua_callback)
>
>
> -- this one hangs
> timer = os.clock()
> while os.clock() - timer <= 5 do end
>
> -- this old school temporisation works :
> --for i=0,300000000 do end
>
> foo:end_callback ()
>
>
>
> And here is my C library:
> /* for testing re-entrance with Lua
> gcc -o libfoo.{so,c} -fvisibility=hidden -pthread -shared -fPIC -Wall
> */
>
> #include <stdio.h>
> #include <unistd.h>
> #include <pthread.h>
> #include <lua.h>
> #include <lauxlib.h>
>
> pthread_t my_thread;
> int thread_is_running = 0;
>
> static void fx_callback (lua_State *L)
> {
> static lua_State *L_context = 0;
> static int index_fx_lua = LUA_REFNIL;
>
> if (L) { // initialised only at startup
> L_context = L; // we store the context
> // and store the function given as Lua parameter
> index_fx_lua = luaL_ref (L, LUA_REGISTRYINDEX);
> if (index_fx_lua == LUA_REFNIL) {
> fprintf(stderr,"luaL_ref : erreur\n");
> }
>
> } else { // it was called from the thread loop
> lua_rawgeti (L_context, LUA_REGISTRYINDEX, index_fx_lua);
> lua_pcall(L_context, 0,0,0);
> }
> }
>
> static void * fx_thread(void *arg)
> {
> while (thread_is_running) {
> fx_callback(0);
> sleep(1);
> }
> return 0;
> }
>
>
> static int set_callback(lua_State *L)
> {
> fx_callback (L);
> thread_is_running = 1;
> pthread_create ( &my_thread, NULL, fx_thread, NULL);
> return 0;
> }
>
> static int end_callback(lua_State *L)
> {
> void *ret = 0;
> fprintf (stderr,"waiting for thread to finish\n");
> thread_is_running = 0;
> pthread_join (my_thread, &ret);
> return 0;
> }
>
> static const struct luaL_Reg foo_fx [] = {
> { "set_callback", set_callback },
> { "end_callback", end_callback },
> {NULL,NULL}
> };
>
>
> #ifdef __linux
> __attribute__((visibility("default"))) int luaopen_libfoo(lua_State *L)
> #else
> __declspec(dllexport) int luaopen_libfoo(lua_State *L)
> #endif
> {
> luaL_register (L, "foo", foo_fx);
> return 1;
> }
--
Robert G. Jakabosky