lua-users home
lua-l archive

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

If i get too annoying asking too many questions, please let me

I've got coroutines working, in a very similar way to the way
that Harmon does in Games Programming Gems 5.

Basically, i have ScriptManager in charge of the main lua state,
and then have ScriptInstances that are in charge of sub lua
states (lua_newthread()). ScriptManager is the only public
interface to all of the lua stuff. When an external wants to
create a new thread of parallel execution, it calls
ScriptManager::createScript(), which new's a ScriptInstance (the
ScriptInstance does a lua_newthread() on the masterState). Then
ScriptManager tells the ScriptInstance to load a chunk and adds
it to its internal ScriptInstances list.

ScriptManager, in its update() call, calls update() on each of
its ScriptInstances. Its told how long the last frame took, and
how long it has to execute this frame. The ScriptInstance calls
lua_resume() and checks the return value. If the return value is
LUA_YIELD then we can try another time slice if there's time
left, if not, return for this frame. If lua_resume() returns
other than LUA_YIELD, then either the script has finished or
there's an error, i don't really care right now.

The ScriptInstance can also be yielded from a lua-bound c-
function called "sleep" which just sets an internal flag inside
ScriptInstance and then calls lua_yield().

So my question is, does this seam like the sane thing to do? Or
am i doing something horribly wrong. Because in my app i have
something similar to this (more complicated, more checks, more
flags, etc) and i'm getting very reproducible memory corruption
_somewhere_. This is visible in a totally corrupt stack trace
during reproducible crashes.

I'm using 5.1w6-cumulative under winxp sp2 using 7.1 with
stl port. Also, some of these calls are across dll boundaries.

I've got ScriptManager and ScriptInstance:

//----------- functions
void luaHook( lua_State* L, lua_Debug* ar ) {
   if ( ar->event == LUA_HOOKCOUNT )
       lua_yield( L, 0 );

class ScriptInstance {
   lua_State* m_SubLuaState;
ScriptInstance( lua_State* masterState ) {
       m_SubLuaState = lua_newthread( masterState );
bool load( const char * buf ) {
       // load stuff
       lua_sethook( m_SubLuaState, luaHook, LUA_MASKCOUNT, 100 );
   bool update( float frameElapsed, float allowed ) {
       Timer timer;
       while ( timer.elapsed() < allowed ) {
           if ( lua_resume( m_SubLuaState, 0 ) == LUA_YIELD ) {
               continue; // can execute more
           } else {
               return false; // false means no more to exec
       return true;

class ScriptManager {
   ScriptManager () {
       m_masterLuaState = lua_open ();
       // open libraries, bind code, etc.
   bool createScript( const char * buf ) {
       ScriptInstance* si = new ScriptInstance( m_masterLuaState );
       if (si->load()) {
           m_scripts.push_back(si); // good to go
       } else {
           delete si; // failed load, remove from existance
   bool update( float elapsed ) {
       for ( int i = 0; i < m_scripts.size(); ++i ) {
           if (!m_scripts [i]->update( elapsed, quantum )) {
               // remove it and delete it

// David Morris-Oliveros
// Camera & Lua Coder
// Team Bondi

Team Bondi Pty Ltd
Level 2, 608 Harris Street
Ultimo, NSW 2007
Tel: +61 (0)2 8218 1500
Fax: +61 (0)2 8218 1507
This email may contain confidential information.  If you are not
the intended recipient, you may not copy or deliver this message to
anyone. In such case, you should destroy this message and kindly
notify the sender by reply email. Opinions, conclusions and other
information in this message that do not relate to the official business
of our firm shall be understood as neither given nor endorsed by it.