is it safe to have two lua thread run parallel on the same lua state without concurrent execution?

687 views Asked by At

we are developing game server using lua.

the server is single threaded, we'll call lua from c++.

every c++ service will create a lua thread from a global lua state which is shared by all service.

the lua script executed by lua thread will call a c api which will make a rpc call to remote server.

then the lua thread is suspened, because it's c function never return.

when the rpc response get back, we'll continue the c code ,which will return to the lua script.

so, we will have multiple lua thread execute parallel on a same global lua state, but they will never run concurrently. and the suspend is not caused but lua yield function, but from the c side.

is it safe to do something like this?

#include <stdio.h>
#include <stdlib.h>
#include <ucontext.h>
#include "lua/lua.hpp"

static ucontext_t uctx_main, uctx_func1, uctx_func2;

lua_State* gLvm;
int gCallCnt = 0;

static int proc(lua_State *L) {
    int iID = atoi(lua_tostring(L, -1));

    printf("begin proc, %s\n", lua_tostring(L, -1));
    if(iID == 1)
    {
        swapcontext(&uctx_func1, &uctx_main);
    }
    else
    {
        swapcontext(&uctx_func2, &uctx_main);
    }
    printf("end proc, %s\n", lua_tostring(L, -1));
    return 0;  
}

static void func1(void)
{
    gCallCnt++;
    printf("hello, func1\n");

    lua_State*thread = lua_newthread (gLvm);

    lua_getglobal(thread, "proc");
    char szTmp[20];
    sprintf(szTmp, "%d", gCallCnt);
    lua_pushstring(thread, szTmp);
    int iRet = lua_resume(thread, gLvm, 1);
    printf("lua_resume return:%d\n", iRet);
}

static void func2(void)
{
    gCallCnt++;
    printf("hello, func2\n");

    lua_State*thread = lua_newthread (gLvm);

    lua_getglobal(thread, "proc");
    char szTmp[20];
    sprintf(szTmp, "%d", gCallCnt);
    lua_pushstring(thread, szTmp);
    int iRet = lua_resume(thread, gLvm, 1);
    printf("lua_resume return:%d\n", iRet);
}



int main(int argc, char *argv[]){
    int iRet = 0;

    gLvm = luaL_newstate();
    luaL_openlibs(gLvm);

    lua_pushcfunction(gLvm, proc);
    lua_setglobal(gLvm, "proc");

    char func1_stack[16384];
    char func2_stack[16384];
    getcontext(&uctx_func1);
    uctx_func1.uc_stack.ss_sp = func1_stack;
    uctx_func1.uc_stack.ss_size = sizeof(func1_stack);
    uctx_func1.uc_link = &uctx_main;
    makecontext(&uctx_func1, func1, 0);

    getcontext(&uctx_func2);
    uctx_func2.uc_stack.ss_sp = func2_stack;
    uctx_func2.uc_stack.ss_size = sizeof(func2_stack);
    uctx_func2.uc_link = &uctx_main;
    makecontext(&uctx_func2, func2, 0);

    swapcontext(&uctx_main, &uctx_func1);

    swapcontext(&uctx_main, &uctx_func2);

    swapcontext(&uctx_main, &uctx_func1);

    swapcontext(&uctx_main, &uctx_func2);

    printf("hello, main\n");

    return 0;
}
0

There are 0 answers