Threadsafe project model

Andreas Pakulat apaku at gmx.de
Thu Jul 15 23:52:03 UTC 2010


On 16.07.10 00:30:20, David Nolden wrote:
> Locking within every single sub-function of the project-model still
> wouldn't solve consistency-problems, like for example:
> 
> thread A: item.setParent(someting)
> thread B: item.setParent(someThingElse)
> thread A: ASSERT(item.parent() == someting) <- BANG

Thats an error in the code calling into the model. There's no way to
solve this problem, except fixing the calling code.

> Or even worse, one thread could delete the imem.

I wasn't trying to fix the inconsistency problems resulting from someone
deleting an item and another "someone" still holding onto the pointer.
We all agree that needs either a shared-pointer or not using pointers at
all to store references to items.

> If you simply define that the project-model belongs to the foreground,
> you can use the foreground lock. In order to have an advantage, the
> parsers need to be designed to only lock it for short times, but
> during those times, the state is guaranteed to be as expected, without
> strange interactions with other threads.

I've already realised that my idea of thread-safe model was completely
bogus and in the same way making write-functions thread-safe. I do not
think though that the foreground lock is useful to solve the problem
that Aleix initially posted a patch for. But maybe I'm misunderstanding
how the foreground lock works. What I'm concerned about is that adding
a new item to the model (which is done from a background thread) will
trigger signals and slots. This in turn will run code outside of our
control and hence may cause problems. So my idea was simply queuing the
signal-delivery into the gui thread, this should be as easy as doing:

if( model() ) {
    QMetaObject::invokeMethod( model(), "rowsAboutToBeInserted", Qt::BlockingQueuedConnection, args );
}

using a blocking-queued-connection here because we want all
"synchronous" slots to be invoked before changing the actual data. For
the simpler 'dataChanged' signal a simple queuedconnection might work
already.

Then the model would still be thread-unsafe and can be declared as such
and still be somewhat usable from a background thread (as far as
notifying the gui of changes is concerned).

Andreas

-- 
You will be misunderstood by everyone.




More information about the KDevelop-devel mailing list