Hi,
Say I have a model subclassed from QAbstractTableModel, which is shown in standard tablewidget.
The model models a global datastore in my program, but this store is internally threadsafe, and it's assumed that multiple threads will modify the data in it, which can change the rowCount() in the model.
I am now wondering how to do this safely. Sure, even in the ideal case, there might be a more or less short period where a view could display outdated data or empty rows or such.
That's fine, but I want a guarantee it wont lead to corruption or crash.
It's clear the begin/endResetModel methods in the model cant be called from another thread.
But then what is the right way to do it?
1) Even if i lock it somehow, is it sufficient to check the row/index in the data() method in order to avoid oob crashes? It should be, right, since the model abstracts my global store, and no other place accesses my global store.
The danger is though that Qt internally implicitly assumes or asserts that all QModelIndex it ever encounters are always QModelIndex::row() < MyModel::rowCount(). I see no guarantee this is not the case.
2) How to communicate the change to the backing store from thread X to the model/view living in the main thread Y.
I suppose a queued signal-slot connection is the easiest way. That is, introduce a new thread_local notification class that lives on thread X, and connect two of its signals to the begin/endResetModel() slots of the model in thread Y.
That way the change is communicated reasonably quickly, and because I check the size in data() (after locking the store), the worst thing that can happen is an empty row or outdated data in the view for a moment.
Problem is that beingResetModel() and endResetModel() will potentially+probably both be processed *after* the modification is already made to the backing store. But that should be ok bc of the first question.
Right?
Thanks
Bookmarks