[Solved] Possible race conditions, issue with gui thread?
-
Hi,
I am building an application to get access to a remote (via LAN) device. There is an option to send a ping request which is supposed to be answered by the device, which it does. As the request is done using a dll file, I thougth it makes sense to call it from within a different thread. Here are the two relevant - from my perspective - functions:
@
void MainWindow::heartBeatTimeout() {
if ( state.lanConnected ) {
if ( state.heartBeatValue != -1 ) {
appendLog( QString( "Heartbeat timeout didn't reply in a timely manner (%1)" ).arg( state.heartBeatValue ) );
ui->actStationary->state = ActivityWidget::Panik;
}
state.heartBeatValue = QTime::currentTime().msec();
appendLog( QString( "before: %1" ).arg( QTime::currentTime().second() ) );
QtConcurrent::run( this, &MainWindow::doPing );
appendLog( QString( "after : %1" ).arg( QTime::currentTime().second() ) );
}
}
void MainWindow::doPing() {
senn_msg_osc( state.getActualDeviceNameAsWChar(), QString( "{"osc":{"ping":%1}}" ).arg( state.heartBeatValue ).toLatin1(), osc_callback );
}
@Now, all "appendLog" calls manipulate the gui, so I think it's correct to do that using the main thread (calling the timer timeout method). In general it works like this, but occasionally (after usually less than a minute) the software crashes. If I uncomment the function call in "doPing()", everything works fine - but I don't get any pings of course.
Any idea for me?
Thanks a lot,
Stephan -
Hi,
You call member functions of the state object from both threads. Are those functions thread-safe?
What is osc_callback?
Do you call the DLL functions in the GUI too?
See the "Synchronizing Threads":http://doc.qt.io/qt-5/threads-synchronizing.html article for more insight.
-
Well, the calls to the "state" object are querying an int value (heartBeatValue) on the one side or a wchar_t* (deviceName) buffer. Both are pure queries, I don't change anything, that's happening in the gui threat. So I would suppose they are fine, pure producer / consumer communication.
osc_callback is a callback function. So the dll calls back onto that function when it receives the answer. What I found out now is, that my call to "senn_msg_osc" blocks until this answer comes which I don't completely understand. As parameter for this callback I use a standard C function which relates back to the main window.
There are function calls from the gui threat as well, yes. Does it actually matter? I must admit the call to the dll are not synchronized, but from the log I would say they are not really occuring in parallel.
Stephan
-
[quote author="StephanWoebbeking" date="1424692250"]Well, the calls to the "state" object are querying an int value (heartBeatValue) on the one side or a wchar_t* (deviceName) buffer. Both are pure queries, I don't change anything, that's happening in the gui threat. So I would suppose they are fine, pure producer / consumer communication.[/quote]If it's all read-only, and you can guarantee that nothing changes state while other threads are reading it, then it's fine.
[quote author="StephanWoebbeking" date="1424692250"]osc_callback is a callback function. So the dll calls back onto that function when it receives the answer. What I found out now is, that my call to "senn_msg_osc" blocks until this answer comes which I don't completely understand. As parameter for this callback I use a standard C function which relates back to the main window.[/quote]So you mean the callback function updates the main window from the other thread? That's would likely cause a crash.
[quote author="StephanWoebbeking" date="1424692250"]There are function calls from the gui threat as well, yes. Does it actually matter?[/quote]It depends on the answer to the fundamental question: Are those DLL functions thread-safe?
-
Deleted
-
Alright, as I wrote above I was just trying to follow up on this... Now I understand even less of it...
I have this line of code which is called from the external dll:
@
qDebug( QString( "%1" ).arg( state.heartBeatValue ).toLatin1() );
@The only thing it does is, that it accesses a public int member variable of "state" which is a private member object (instance) of my main window class. It works perfectly, until I hide this main window!!! The events from the dll still arrive, so this is called again and the application crashes without further information. Without this line everything is fine, so far.
It LOOKS very much like the variable "state" is not available to this externally called method when the main window is hidden. Is this possible??? I have really no idea where else I should be looking for? Any hints / ideas what usually makes applications crush are much appreciated.
Thanks,
Stephan -
This becomes really weird, I will close this thread and open another one to present my newest findings...
Thanks for you help, look forward for my next thread. ;)
Stephan