View Full Version : MySql: my_thread_global_end(): 1 threads didn't exit
mentalmushroom
16th September 2014, 14:13
When QSqlDatabase::removeDatabase() is called from a different thread than QSqlDatabase::addDatabase() was called from, I get the following error message:
Error in my_thread_global_end(): 1 threads didn't exit
It is easy to reproduce with the following code sample even without MySql database. But it seems to happen on Ubuntu and NOT on Windows.
#include <QtCore>
#include <QtSql>
class Client: public QObject
{
Q_OBJECT
public:
Client();
~Client();
public slots:
void start();
signals:
void done();
}; // Client
Client::Client()
{
QSqlDatabase::addDatabase("QMYSQL", "my_connection");
}
Client::~Client()
{
}
void Client::start()
{
// we could do some work here, but for the test simply remove the connection
QSqlDatabase::removeDatabase("my_connection");
emit done();
}
int main(int argc, char* argv[])
{
QCoreApplication app(argc, argv);
QThread t;
Client client;
client.moveToThread(&t);
QObject::connect(&t, SIGNAL(started()), &client, SLOT(start()));
QObject::connect(&client, SIGNAL(done()), &t, SLOT(quit()));
QObject::connect(&t, SIGNAL(finished()), &app, SLOT(quit()));
t.start();
return app.exec();
}
#include "main.moc"
What am I doing wrong?
wysota
16th September 2014, 16:38
What am I doing wrong?
You are removing the database from a wrong thread. QSqlDatabase (and friends) objects are not to be used from within different threads.
Threads and the sql module
mentalmushroom
19th September 2014, 07:17
Ok, good to know. But I noticed the error happens when I add and remove the connection from the same thread either, but less regular.
The issue can be noticed with the following code sample:
#include <QtCore>
#include <QtSql>
class Client: public QRunnable
{
public:
virtual void run();
};
void Client::run()
{
{
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", QString::number((unsigned long long)QThread::currentThreadId()));
db.setHostName("localhost");
db.setDatabaseName("test");
db.setUserName("me");
db.setPassword("mypass");
db.open();
//QSqlQuery q(strQuery);
}
QSqlDatabase::removeDatabase(QString::number((unsi gned long long)QThread::currentThreadId()));
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QThreadPool pool;
pool.setMaxThreadCount(100);
for (int i = 0; i < 100; ++i)
{
Client *client = new Client;
bool started = pool.tryStart(client);
Q_ASSERT(started);
}
pool.waitForDone();
//return a.exec();
return 0;
}
Here goes the output of two successive runs:
mushroom@ubuntu:~/projects/mysqltest/mysqlthread/debug$ ./mysqlthread
Error in my_thread_global_end(): 48 threads didn't exit
mushroom@ubuntu:~/projects/mysqltest/mysqlthread/debug$ ./mysqlthread
Error in my_thread_global_end(): 33 threads didn't exit
Error in my_thread_global_end(): 85 threads didn't exit
wysota
19th September 2014, 09:15
Close the database first before removing it.
mentalmushroom
19th September 2014, 12:57
I've updated the code, so it is closed:
#include <QtCore>
#include <QtSql>
class Client: public QRunnable
{
public:
virtual void run();
};
void Client::run()
{
{
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", QString::number((unsigned long long)QThread::currentThreadId()));
db.setHostName("localhost");
db.setDatabaseName("test");
db.setUserName("me");
db.setPassword("mypass");
db.open();
db.close(); // ! close the database before removing it !
}
QSqlDatabase::removeDatabase(QString::number((unsi gned long long)QThread::currentThreadId()));
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QThreadPool pool;
pool.setMaxThreadCount(100);
for (int i = 0; i < 100; ++i)
{
Client *client = new Client;
bool started = pool.tryStart(client);
Q_ASSERT(started);
}
pool.waitForDone();
return 0;
}
The error still persists:
mushroom@ubuntu:~/projects/mysqltest/mysqlthread/debug$ ./mysqlthread
Error in my_thread_global_end(): 51 threads didn't exit
Error in my_thread_global_end(): 65 threads didn't exit
gfernandes
21st October 2014, 12:50
Hi,
I have the same issue. Did you resolve your issue? If yes, could you please share your solution?
Thank you
mentalmushroom
22nd October 2014, 09:35
No, I didn't, but so far I can't see any obvious issues, except that warning message. However, I've reported it to the bug tracker (https://bugreports.qt-project.org/browse/QTBUG-41483?page=com.atlassian.streams.streams-jira-plugin:activity-stream-issue-tab). Vote for it, if it worries you.
danadam
5th May 2015, 15:36
From what I found out, there may be two causes for that:
QSqlDatabase::addDatabase() and QSqlDatabase::removeDatabase() are not entirely thread-safe when using MySQL driver (maybe also when using other drivers, I didn't check them)
MySQL driver doesn't clean up properly after itself when call to QSqlDatabase::open() fails.
See my response to your bug for more details.
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.