lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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;
}