Hi,

An application I'm currently working on is interacting with a SQLite database 
for loading GUI components like images, buttons, texts, etc. It is also using 
it for different things like user settings, which usually resides in a 
different thread than the GUI thread. In a sense the application is using the 
QtSqlite module wrong, because it is sharing a connection between threads. To 
solve issue I created a SQL serializer which, the name implies, serializes all 
queries through one thread which has its own local database connection. How it 
basically works is that any thread can enqueue a SQL query string into a 
message queue. The serializer will then process the queries one by one and 
notifies the thread which requested a query to be processed once the execution 
is finished.

When a thread is scheduling a query to be processed we simply call a function 
which takes care of (thread-safe) putting the request in our message queue and 
returns an object, which I call SqlReply. The user can then connect a SLOT to 
the finished SIGNAL of this object, or the user can call a blocking function, 
which will block until the query is processed by the serializer. Once the 
serializer starts processing the request, the software creates a local 
QSqlQuery object on the serializer thread. This QSqlQuery object is used to 
execute the query string which was scheduled by another thread. Once the 
execution is finished successfully, we copy and assign the local QSqlQuery 
object to another QSqlQuery object which resides inside the SqlReply. After 
that we delete the local copy inside the serializer thread and call the 
finished signal of the SqlReply object, or wake up our wait condition in the 
blocking function. Once we return from the blocking function of the SqlReply 
object (or the connected SLOT is called), we can call a function on the 
SqlReply object which will return the QSqlQuery object we previously copied and 
assigned from the serializer thread (so basically we moved the executed 
QSqlQuery object from the serializer thread to the thread which initially 
created the query request). So far this is working fine, however when we delete 
the SqlReply (and effectively the last reference to the QSqlQuery object, I 
verified that the reference counter is indeed '1' at this point) the resources 
allocated for the execution of the query string are not being free'd. I'm not 
sure why this is forming a problem as the query is created in the same thread 
where I created my database connection. However it might problematic if the 
results are not cached after until I actually retrieve values from the 
QSqlQuery. Because the retrieval of values will always happen on a different 
thread (we copied the QSqlQuery object created in the serializer thread to 
thread where we created the SqlReply). Can someone confirm that the way I'm 
currently doing this is indeed not supported by QT and/or the underlying SQLite 
driver?

Note:
I can cache the results and give back those cached results to the other 
threads, instead of using the QSqlQuery class. However, because the current 
program is using the QSqlQuery class extensively I'd like to remain using that 
over the cached results to minimize changes in the current software.

Regards,

Mike Neuhaus

_______________________________________________
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest

Reply via email to