[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Will lua_sethook work for the later created coroutine?
- From: 孙世龙 sunshilong <sunshilong369@...>
- Date: Thu, 14 Jan 2021 10:04:40 +0800
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);