MySql: my_thread_global_end(): 1 threads didn't exit
When QSqlDatabase::removeDatabase() is called from a different thread than QSqlDatabase::addDatabase() was called from, I get the following error message:
Quote:
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.
Code:
#include <QtCore>
#include <QtSql>
{
Q_OBJECT
public:
Client();
~Client();
public slots:
void start();
signals:
void done();
}; // Client
Client::Client()
{
}
Client::~Client()
{
}
void Client::start()
{
// we could do some work here, but for the test simply remove the connection
emit done();
}
int main(int argc, char* argv[])
{
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?
Re: MySql: my_thread_global_end(): 1 threads didn't exit
Quote:
Originally Posted by
mentalmushroom
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
Re: MySql: my_thread_global_end(): 1 threads didn't exit
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:
Code:
#include <QtCore>
#include <QtSql>
class Client: public QRunnable
{
public:
virtual void run();
};
void Client::run()
{
{
db.setHostName("localhost");
db.setDatabaseName("test");
db.setUserName("me");
db.setPassword("mypass");
db.open();
//QSqlQuery q(strQuery);
}
}
int main(int argc, char *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:
Quote:
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
Re: MySql: my_thread_global_end(): 1 threads didn't exit
Close the database first before removing it.
Re: MySql: my_thread_global_end(): 1 threads didn't exit
I've updated the code, so it is closed:
Code:
#include <QtCore>
#include <QtSql>
class Client: public QRunnable
{
public:
virtual void run();
};
void Client::run()
{
{
db.setHostName("localhost");
db.setDatabaseName("test");
db.setUserName("me");
db.setPassword("mypass");
db.open();
db.close(); // ! close the database before removing it !
}
}
int main(int argc, char *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:
Quote:
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
Re: MySql: my_thread_global_end(): 1 threads didn't exit
Hi,
I have the same issue. Did you resolve your issue? If yes, could you please share your solution?
Thank you
Re: MySql: my_thread_global_end(): 1 threads didn't exit
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. Vote for it, if it worries you.
Re: MySql: my_thread_global_end(): 1 threads didn't exit
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.