[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Thread in library which call Lua function
- From: jseb <gmane2010@...>
- Date: Fri, 15 Apr 2011 20:21:28 +0200
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
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;
}