Will lua_sethook work for the later created coroutine?

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Will lua_sethook work for the later created coroutine?

孙世龙 sunshilong
Hi, list

Will lua_sethook work for the later created coroutine?

1.The answer seems to be yes after I carelly studied the related
code snippet.The later created coroutine will use the same
hook function as the former lua thread.Here is the related code
snippet:

static int luaB_cocreate (lua_State *L) {
  lua_State *NL;
  NL = lua_newthread(L);
  ...
}

LUA_API lua_State *lua_newthread (lua_State *L) {
  lua_State *L1;

  /* create new thread */
  L1 = &cast(LX *, luaM_newobject(L, LUA_TTHREAD, sizeof(LX)))->l;
  L1->tt = LUA_TTHREAD;
  ...
  L1->hook = L->hook;
 ...
}

2.The answer seems to be yes after I did a test:
/*C code*/
#include "lua.hpp"
#include <iostream>
#include <assert.h>
#include <fstream>

void hook(lua_State *L, lua_Debug *ar)
{
       std::cout << (void*)L << std::endl;
}

int main()
{
    struct lua_State *L = luaL_newstate();

    luaL_openlibs(L);
    lua_sethook(L, hook, LUA_MASKLINE, 0);

    int ret;

    std::string fileName("co.lua");
    if(fileName.empty())
    {
        std::cout << "the filename is empty" << std::endl;
        return -1;
    }

    std::ifstream fileScript(fileName, fileScript.in|std::ios::ate);

    if(!fileScript.is_open())
    {
        std::cout << "open file failed" << std::endl;
        return -2;
    }

    size_t size = fileScript.tellg();

    if(size <= 0)
    {
        std::cout << "file has no valid content" << std::endl;
        return -3;
    }

    std::string textCont(size, '\0');

    fileScript.seekg(0);
    fileScript.read(&textCont[0], size);

    if((ret=luaL_loadbuffer(L, textCont.data(), textCont.length(),
"co.lua")) == LUA_OK)
    {
        if((ret=lua_pcall(L, 0, LUA_MULTRET, 0)) != LUA_OK)
        {
            std::cout << "error in invoking lua_pcall():" << ret << std::endl;
            if(lua_isstring(L, -1))
            {
                const char *errMsg = lua_tostring(L, -1);
                lua_pop(L, 1);
                std::cout << "script run encounter err:" << errMsg << std::endl;
            }
        }
    }
}

/*lua code*/
function foo ()
    print("foo" )
    count = 0;
    while( 0<1 )
    do
       count = count + 1;
       print("count=", count);
       if count>1000 then
         break
       end
    end

    return coroutine.yield()
  end

 co = coroutine.create(function ()
        foo();
        print("hello world")
        print("test")
        print(type(co))
        a=1;
        return
  end)

I can see two different addresses (that are outputed) in the console indeed.

3.But the answer seems to be no since this post below.
As per the post(
http://lua-users.org/lists/lua-l/2011-06/msg00513.html),
which says that[emphasis mine]:
> Can lua_sethook be called on a coroutine?  Will it interrupt
> only the coroutine or also the main "thread/coroutine"?
For Lua you need to set it on each coroutine separately. This can
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
get difficult, because you are not notified when a new coroutine
is created. For LuaJIT you only need to set it once and it applies
to all coroutines.
> Here is an example:
>
> Should lua_sethook call "hook" on l thread or on both l and j threads?
With LuaJIT it applies to both (output is abababa...). With Lua it
only applies to 'l' (output is bbbb... because 'j' never yields).
>     lua_sethook(l, hook, LUA_MASKLINE, 0);