Page 1 of 1

Multi-thread issue

PostPosted: Thu Dec 31, 2020 10:20 am
by mdw
Beginning with Qt 5.11 LTS QSqlDatabase::database() verifies the execution on the correct thread: https://code.qt.io/cgit/qt/qtbase.git/t ... cpp?h=5.11 lines 234 ff.

QxOrm's QxSqlDatabase::getDatabaseByCurrThreadId() uses this call under the assumption that the thread identifiers remain unaltered over the whole lifetime over the program:
https://github.com/QxOrm/QxOrm/blob/e40da423624fc73fbf7d66d64b482d138fa5fd56/src/QxDao/QxSqlDatabase.cpp#L596

Unfortunately this assumption does not hold in general. For instance it is not the case on GNU/Linux where thread ID reuse happens on frequent thread allocation and destruction. Under POSIX-compliant systems QThread::currentThreadId() gets mapped to pthread_self() which is guaranteed to return a unique identifier at a time, but not over the whole lifetime over the process.

Man-page documentation states:
Thread IDs are guaranteed to be unique only within a process. A thread ID may be reused after a terminated thread has
been joined, or a detached thread has terminated.


When thread ID reuse takes place QSqlDatabase::database() just returns a warning
QSqlDatabasePrivate::database: requested database does not belong to the calling thread. without any valid connection
since QxORM thinks that it would still be dealing with the same thread but effectively it's not.

Hence I propose a second check to QxOrm's QxSqlDatabase::getDatabaseByCurrThreadId() last if condition:

Code: Select all
...
    if (! m_lstDbByThread.contains(lCurrThreadId)) { return createDatabase(dbError); }
    QString sDbKey = m_lstDbByThread.value(lCurrThreadId);
    if (! QSqlDatabase::contains(sDbKey) || ! QSqlDatabase::database(sDbKey, false).isValid()) { return createDatabase(dbError); }
    return QSqlDatabase::database(sDbKey);

Re: Multi-thread issue

PostPosted: Mon Jan 04, 2021 8:30 am
by qxorm
Hello,

Thx, we will continue this topic on GitHub : https://github.com/QxOrm/QxOrm/issues/42