lua-users home
lua-l archive

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


Below is Amped's approach to Win32 multithreading.  This works on the
Xbox, too.  The Lua 4.1 Alpha code base had to be modified to make this
work.  I will discuss the changes below.

First, the Lua 4.1 LUA_USERSTATE #define to allow inclusion of state
code into the lua_State structure in lstate.h was not sufficient to
bring this online.  No code needs to be added to the lua_State.  The
code to support "proper" multithreading (through this technique anyway)
has to be in global_State.

Perhaps the Lua team may consider allowing access to the global_State
through a similar macro.  Although, as I said in a past email, I have
one built Lua .lib that works across multiple projects.  It does bite to
have to have multithreading support for ALL of them.

-------------------------------------

At the bottom of the global_State structure definition in lstate.h, add
the following three lines:

  void* lockData;
  void (*lockFunc)(void*);
  void (*unlockFunc)(void*);

-------------------------------------

In lstate.c, add the following three lines to the bottom of the
f_luaopen() function:

    G(L)->lockData = NULL;
    G(L)->lockFunc = NULL;
    G(L)->unlockFunc = NULL;

-------------------------------------

In lstate.c, add the following function:

LUA_API void lua_setlockfunctions(lua_State *L, void (*lockFunc)(void
*),
                                  void (*unlockFunc)(void *), void
*lockData)
{
  L->G->lockFunc = lockFunc;
  L->G->unlockFunc = unlockFunc;
  L->G->lockData = lockData;
}

-------------------------------------

In lua.h, add the following #defines and function declaration:

#define lua_lock(L)		if (L->G  &&  L->G->lockFunc)
(*L->G->lockFunc)(L->G->lockData)
#define lua_unlock(L)	if (L->G  &&  L->G->unlockFunc)
(*L->G->unlockFunc)(L->G->lockData)
LUA_API void lua_setlockfunctions(lua_State *L, void (*lockFunc)(void
*), void (*unlockFunc)(void *), void *lockData);

-------------------------------------

Add the following functions to your code:

static void ScriptLock(void* data)
{
	CRITICAL_SECTION* cs = (CRITICAL_SECTION*)data;
	::EnterCriticalSection(cs);
}


static void ScriptUnlock(void* data)
{
	CRITICAL_SECTION* cs = (CRITICAL_SECTION*)data;
	::LeaveCriticalSection(cs);
}

-------------------------------------

Create a new Lua state and register the functions:

lua_State* L = lua_open(0);

CRITICAL_SECTION* cs = new CRITICAL_SECTION;
::InitializeCriticalSection(cs);
lua_setlockfunctions(m_state, ScriptLock, ScriptUnlock, cs);

-------------------------------------

Create a Windows thread and add a new lua_State, keying off the master
state from the step above:

lua_State* threadState = lua_newthread(L, 0);

-------------------------------------

Voila!  Multithreaded Lua (hey, it works for me!).

Thanks,
Joshua Jensen
Amped: Freestyle Snowboarding
http://www.xbox.com/Games/sports/amped.htm