Nepomuk Tasks: KActivityManager Crash

After a little silence during which I was occupied with Eastern and OpenLink related work I bring you news about the second Nepomuk task: the KActivityManager crash.

Ivan Cukic already “fixed” the bug by simply not using Nepomuk but an SQLite backend (at least that is how I understood it, correct me if I am wrong). However, I wanted to fix the root of the original problem.

Soprano provides the communication channel between Nepomuk and its clients. It is based on a very simple custom protocol going through a local socket. So far QLocalSocket, ie. Qt’s implementation was used. The problem with QLocalSocket is that it is a QObject. Thus, it cannot live in two threads at the same time. The hacky solution was to maintain one socket per thread. Sadly that resulted in complicated maintenance code which was impossible to get right. Hence crashes like #269573 or #283451 (basically any crash involving The Soprano::ClientConnection) were never fixed.

A few days ago I finally gave up and decided to get rid of QLocalSocket and replace it with my own implementation. The only problem is that in order to keep Windows compatibility I had to keep the old implementation around by adding quite a lot of #ifdefs.

And now I could use some testers for a Soprano client library that does only create a single connection to the server instead of one per thread. I already pushed the new code into Soprano’s git master. So all you need to do is run KDE on top of that.

Oh, and while at it I finally fixed the problem with re-connecting of clients. So now a restart of Nepomuk will no longer leave the clients with dangling connections, unable to perform queries. That fix, however, is in kdelibs.

Well, the day was long, I am tired, and this blog post feels a little boring. So before in addition to that it gets too long I will stop.

11 thoughts on “Nepomuk Tasks: KActivityManager Crash

  1. Test result: Doesn’t compile :)

    I fixed one error, but still fails linking in sopranocmd.

    diff –git a/client/clientconnection.cpp b/client/clientconnection.cpp
    index 2246c10..3565f4d 100644
    — a/client/clientconnection.cpp
    +++ b/client/clientconnection.cpp
    @@ -821,7 +821,7 @@ bool Soprano::Client::ClientConnection::isConnected()
    return ( d->socketStorage.hasLocalData() &&
    isConnected( d->socketStorage.localData()->socket() ) );
    – return( d->socket != 0 && d->socket.isConnected() );
    + return( d->socket != 0 && d->socket->isConnected() );

  2. Yay! This is truly excellent news.

    Thanks a million. Someday, when the Linux desktop has taken over the world, people will remember you as “they guy who finally made this semantic thingy work”.

  3. Could you elaborate with your problem about accessing a QObject from different threads? Of course they cannot “live” in different threads, but they can’t have multiple parents anyways… I wonder what you tried to do or what you mean by “living” in two threads.

    Generally, accessing a shared QObject from different threads is perfectly fine as long as you only call thread safe methods. If QLocalSocket is not threadsafe, than write a simple wrapper that ensures properly synchonization using QMutex or similar.

    • QLocalSocket does event processing internally. There is nothing you can do about it as a user of the class. Thus, one can only use one QlocalSocket/QIODevice from one thread, never from more than one.

          • yes and what about synchronization using a mutex e.g.? the class is not threadsafe after all, so accessing it from multiple threads must be synchronized. anyhow without some code to look at I can’t say anything except that the statement “qobject cannot live in two threads” is completely bogus.

            • (Edit: I removed a previously posted code example since it was pointless)
              The fact is that I cannot remember the details. This problem has been there for years. I am fairly certain that at least at one point I talked to Thiago about it. However, in order to explain it in detail I would have to go through commit messages and code to recall it all. All I remember is that it has to do with events or timers that are used internally and the problem of not being able to pull an object into a thread.

  4. You are mostly right – in 4.9, the nepomuk plugin was replaced (for performance reasons) by a sqlite+nepomuk plugin (like we talked about in Randa). For 4.8.2, it is just disabled.

    The bug is resolved (was filed against kamd, and I haven’t seen a response from nepomuk team on it) while the underlying issue remained. Maybe I should have put ‘upstream’.

  5. I am very happy with this fix, and would be happy to test it. Is there a Kubuntu package somewhere I can get to do the testing?

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s