mkottman/lqt — Issue #18: lqt is not coroutine-safe; objects created in coroutines other than the one that loaded lqt misbehave
Author: ToxicFrog
Created: 2012-01-23 04:08:29+00:00
State: open

Specifically, you can create objects in threads other than the loader, but you cannot then connect their signals to anything, or strange error messages from QCoreApplication::exec or QCoreApplication::processEvents (depending on which one your mainloop is using) will result.

Note that you can still call methods on the object from other threads, and there's no requirement that app.exec() be called from the same thread that created the object - but if the object itself is not created in the same thread that called require "qtcore", sadness occurs.

Here's a test case:

```
require "qtcore"
require "qtgui"

local app = QApplication(1, arg)

local window

coroutine.resume(coroutine.create(function()
window = QPushButton("click me")
end))

window:connect("2clicked()", print)
window:show()
app.exec()
--
-- output: QApplication::exec(QPushButton*): incorrect or extra arguments, expecting: .
```

The expected output is a bunch of "userdata" from the connected print().

Rearranging the code so that the requires of qtcore are in a separate coroutine and the creation of the QPushButton is in main results in a different but no less odd error message:

```
coroutine.resume(coroutine.create(function()
require "qtcore"
require "qtgui"
end))

local app = QApplication(1, arg)

local window
window = QPushButton("click me")

window:connect("2clicked()", print)
window:show()

app.exec()
--
-- output: attempt to call a nil value
```

Moving everything into main, or everything into the same coroutine, works fine. (I don't know what happens if you require "qtcore" from one thread and "qtgui" from a different one.)

Based on this behaviour, I suspect that when loaded, lqt is remembering the lua_State * that loaded it and is sometimes interacting with that stack even when it should be interacting with the stack that it was called from, but honestly I'm not even sure where to start debugging this, let alone writing a patch.