nyaruko
9th November 2014, 18:50
I have the following code which is called by many threads using a thread pool:
QByteArray PureImageCache::GetImageFromCache(MapType::Types type, Point pos, int zoom)
{
lock.lockForRead();
QByteArray ar;
if(gtilecache.isEmpty()|gtilecache.isNull())
return ar;
QString dir=gtilecache;
Mcounter.lock();
qlonglong id=++ConnCounter;
Mcounter.unlock();
QString db=dir+"Data.qmdb";
{
QSqlDatabase cn;
cn = QSqlDatabase::addDatabase("QSQLITE",QString::number(id));
cn.setDatabaseName(db);
cn.setConnectOptions("QSQLITE_ENABLE_SHARED_CACHE");
if(cn.open())
{
QSqlQuery query(cn);
query.exec(QString("SELECT Tile FROM TilesData WHERE id = (SELECT id FROM Tiles WHERE X=%1 AND Y=%2 AND Zoom=%3 AND Type=%4)").arg(pos.X()).arg(pos.Y()).arg(zoom).arg((int) type));
query.next();
if(query.isValid())
{
ar=query.value(0).toByteArray();
//qDebug()<<"Got";
}else{
//qDebug()<<"Miss";
}
cn.close();
}
}
QSqlDatabase::removeDatabase(QString::number(id));
lock.unlock();
return ar;
}
However, I have met one crash (not every time) right after I call the:
cn = QSqlDatabase::addDatabase(“QSQLITEâ€,QS tring::number(id));
function. And the call stack says the error is:
Debug Assertion Failed!
File:f:\dd\vctools\crt_bld\self_x86\crt\src\dbgdel .cpp
Line: 52
Expression:_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
The cause is within the = operator, it call an atomic assign where inside that atomic assign, there's a delete function cause the crash.
I noticed that there's a shared_null pointer inside the default constructor of QSqlDatabase.
Here is the thing:
The default constructor of QSqlDatabase used a shared_null.
Note that the shared_null is an object indicating an invalid database, not a plain null pointer.
Here is the code: http://code.woboq.org/qt5/qtbase/src/sql/kernel/qsqldatabase.cpp.html#_ZN19QSqlDatabasePrivate11sh ared_nullEv
Could it be that the delete is called on to delete the shared_null which is essentially some static variable and caused the crash?
How could I avoid this and continue using QSqlDataBase safely in multi-thread senario?
QByteArray PureImageCache::GetImageFromCache(MapType::Types type, Point pos, int zoom)
{
lock.lockForRead();
QByteArray ar;
if(gtilecache.isEmpty()|gtilecache.isNull())
return ar;
QString dir=gtilecache;
Mcounter.lock();
qlonglong id=++ConnCounter;
Mcounter.unlock();
QString db=dir+"Data.qmdb";
{
QSqlDatabase cn;
cn = QSqlDatabase::addDatabase("QSQLITE",QString::number(id));
cn.setDatabaseName(db);
cn.setConnectOptions("QSQLITE_ENABLE_SHARED_CACHE");
if(cn.open())
{
QSqlQuery query(cn);
query.exec(QString("SELECT Tile FROM TilesData WHERE id = (SELECT id FROM Tiles WHERE X=%1 AND Y=%2 AND Zoom=%3 AND Type=%4)").arg(pos.X()).arg(pos.Y()).arg(zoom).arg((int) type));
query.next();
if(query.isValid())
{
ar=query.value(0).toByteArray();
//qDebug()<<"Got";
}else{
//qDebug()<<"Miss";
}
cn.close();
}
}
QSqlDatabase::removeDatabase(QString::number(id));
lock.unlock();
return ar;
}
However, I have met one crash (not every time) right after I call the:
cn = QSqlDatabase::addDatabase(“QSQLITEâ€,QS tring::number(id));
function. And the call stack says the error is:
Debug Assertion Failed!
File:f:\dd\vctools\crt_bld\self_x86\crt\src\dbgdel .cpp
Line: 52
Expression:_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
The cause is within the = operator, it call an atomic assign where inside that atomic assign, there's a delete function cause the crash.
I noticed that there's a shared_null pointer inside the default constructor of QSqlDatabase.
Here is the thing:
The default constructor of QSqlDatabase used a shared_null.
Note that the shared_null is an object indicating an invalid database, not a plain null pointer.
Here is the code: http://code.woboq.org/qt5/qtbase/src/sql/kernel/qsqldatabase.cpp.html#_ZN19QSqlDatabasePrivate11sh ared_nullEv
Could it be that the delete is called on to delete the shared_null which is essentially some static variable and caused the crash?
How could I avoid this and continue using QSqlDataBase safely in multi-thread senario?