I am developing a test tool to generate waveform from PC parallel port. This tools is designed to generate any pattern of waveform with timing accuracy of ms, so I use Lua script to define the waveform pattern, the GUI start new QThread to run the script when user clicks [Start] button.
The following three functions for Lua are implemented as C++ global functions:
- pwrite: write data to parallel port.
- msleep: wait for certain ms (implemented using nanosleep())
- print: overwrite Lua default print function, this one will append message to one QTextEdit widget.
when pwrite is called, the written data is stored in global variable, then the GUI is updated with 20ms interval to update the parallel port data on the GUI. (this 20ms interval refresh is not a good design, but I haven't figure out how to use signal to make GUI update when data changed).
The tool is basically functional now. The waveform output has no problem, but the parallel port data updating has some problem:
When Lua call msleep, GUI thread is stopped, the parallel port data updates only after msleep ends.
So my questions are:
How to implement the sleep method so that it won't stop the GUI thread from updating?
How to implement the pwrite, so that the GUI can receive a signal to update the parallel port data when written data changed?
Program GUI as the link below:

The related code:
/* common.cpp file */
int L_MSleep(lua_State* l)
{
int milisec=0;
struct timespec req={0, 0};
time_t sec;
milisec=luaL_optint(l,1,0); // obtain parameter
if (milisec==0)
return 0;
sec=(int)(milisec/1000);
milisec=milisec-(sec*1000);
req.tv_sec=sec;
req.tv_nsec=milisec*1000000L;
while(nanosleep(&req,&req)==-1)
continue;
return 1;
}
/* LuaRunner.cpp file */
LuaRunner::LuaRunner(QObject *parent) :
QThread(parent)
{
runlua = false;
}
void LuaRunner::run()
{
QString err = "";
runlua = true;
LUA_RunScript(this->ff, err);
runlua = false;
if(err != "")
{
emit errorMessage(err);
}
}
int LuaRunner::LUA_RunScript(QString ff, QString &err)
{
L = lua_open();
luaL_openlibs(L);
if (luaL_loadfile(L, ff.toAscii()) || lua_pcall(L, 0, 0, 0))
{
err = QString(lua_tostring(L, -1));
return -1;
}
lua_register(L, "ssleep", L_SSleep);
lua_register(L, "msleep", L_MSleep);
lua_register(L, "pwrite", L_PortWrite);
lua_register(L, "print", L_Log);
lua_getglobal(L, "dotest");
if (!lua_isfunction(L, -1))
{
err = QString("Test function(dotest) should be a function");
return -1;
}
if(lua_pcall(L, 0, 0, 0))
{
err = QString(lua_tostring(L, -1));
return -1;
}
lua_close(L);
return 0;
}