lua-users home
lua-l archive

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


Hi all,

While migrating my application from Lua 5.1 to Lua 5.3, I'm trying correct multi-threading issues I'm encounterning. I already created some discusses about that on this mailing list ... but, clearly, I'm missing something :)

I'm using dedicated States using luaL_newstate() for each and every thread created, and my issue is pass a function to execute from my master threads to slave ones. I'm using 2 mechanisms (in both cases, L is the State from the master thread, that parsed the source code ) :

1/ The function to call is passed as a function resulting following code :

static void *launchfunc(void *arg){
    if(lua_pcall( (lua_State *)arg, 0, 1, 0))
        fprintf(stderr, "*E* (launch) %s\n", lua_tostring((lua_State *)arg, -1));
    
    lua_close((lua_State *)arg);
    return NULL;
}

int SelDetach( lua_State *L ){
    if(lua_type(L, 1) != LUA_TFUNCTION ){
        lua_pushnil(L);
        lua_pushstring(L, "Function needed as 1st argument of Selene.Detach()");
        return 2;
    }

    pthread_t tid;    /* No need to be kept */
    lua_State *tstate = luaL_newstate(); /* Initialise new state for the thread */
    assert(tstate);
    luaL_openlibs( tstate );
    lua_xmove( L, tstate, 1 );

    if(pthread_create( &tid, &thread_attr, launchfunc,  tstate) < 0){
        fprintf(stderr, "*E* Can't create a new thread : %s\n", strerror(errno));
        lua_pushnil(L);
        lua_pushstring(L, strerror(errno));
        return 2;
    }

    return 0;
}

In this case :
* my slave function CAN access to global variables (which has to be avoided as dangerous : there is no management of concurrent acces).
* I have no issue when comparing strings.

2/ The function to call is passed only as a reference resulting following code :

        ...
        lua_pushstring(L, "func");    /* retreaving from arguments tables
        lua_gettable(L, -2);
        if( lua_type(L, -1) != LUA_TFUNCTION )
            lua_pop(L, 1);    /* Pop the result */
        else {
            lua_xmove( L, eclient->L, 1 );    /* Move the function to the callback's stack */
            func = luaL_ref(eclient->L,LUA_REGISTRYINDEX);    /* Reference the function in callbacks' context */
        }
        ...

        ...
        lua_State *tstate = luaL_newstate();    /* State dedicated to this thread */
        assert(tstate);
        luaL_openlibs( tstate );
                
        pthread_mutex_lock( &ctx->access_ctrl );    /* Exclusive access to the broker's stat needed */
        lua_rawgeti( ctx->L, LUA_REGISTRYINDEX, tp->func);    /* retrieves the function */
        lua_xmove( ctx->L, tstate, 1 );
        pthread_mutex_unlock( &ctx->access_ctrl );
        lua_pushstring( tstate, topic);
        lua_pushstring( tstate, cpayload);
        if(lua_pcall( tstate, 2, 1, 0)){    /* Call Lua callback function */
            fprintf(stderr, "*E* (msg arrival) %s\n", lua_tostring(tstate, -1));
            lua_pop(tstate, 2); /* pop error message and NIL from the stack */
        } else if(tp->trigger != LUA_REFNIL){
            if(lua_toboolean(tstate, -1))
                pushtask( tp->trigger, tp->trigger_once );
            lua_pop(tstate, 1);    /* remove the return code */
        }
        lua_close( tstate ); /* Remove this thread own state */
        ...

In this case, global variables are unknown BUT I'm in trouble when I'm comparing a variable with a string like
    if myvar == "toto" then ...
even with myvar has the good value, the comparison is failling.

So, what should I do to correctly call a function in another thread ?

Thanks

Laurent