[soprano] backport some upstream fixes

Rex Dieter rdieter at fedoraproject.org
Mon Dec 24 18:42:53 UTC 2012


commit 2a9f5538eb4892d2eb10982ba61cccd0576bbd87
Author: Rex Dieter <rdieter at math.unl.edu>
Date:   Mon Dec 24 12:43:12 2012 -0600

    backport some upstream fixes

 0001-No-qDebug-output-in-non-debug-modes.patch     |   36 ++
 ...override-QT_USE_FILE-to-fix-include-order.patch |   39 ++
 0003-Fix-100-CPU-usage-when-killing-virtuoso.patch |   48 +++
 0004-Check-return-values-from-write-calls.patch    |  414 ++++++++++++++++++++
 ...-due-to-using-the-same-QUrls-in-multiple-.patch |   73 ++++
 ...Use-QThreadStorage-instead-of-a-QHash-wit.patch |   75 ++++
 ...rCache-Use-QThreadStorage-instead-of-a-QH.patch |   74 ++++
 0008-Client-Cache-the-current-bindings.patch       |   90 +++++
 ...e-sending-of-LiteralValue-over-the-socket.patch |  213 ++++++++++
 ...-on-destruction-of-ClientModel-if-nepomuk.patch |   30 ++
 soprano.spec                                       |   28 ++-
 11 files changed, 1117 insertions(+), 3 deletions(-)
---
diff --git a/0001-No-qDebug-output-in-non-debug-modes.patch b/0001-No-qDebug-output-in-non-debug-modes.patch
new file mode 100644
index 0000000..d48b361
--- /dev/null
+++ b/0001-No-qDebug-output-in-non-debug-modes.patch
@@ -0,0 +1,36 @@
+From bdc1aec70aab30b075558b98657bac55d4845963 Mon Sep 17 00:00:00 2001
+From: Vishesh Handa <me at vhanda.in>
+Date: Tue, 31 Jul 2012 22:27:16 +0530
+Subject: [PATCH 01/10] No qDebug output in non debug modes
+
+Soprano should not emit debug output when compiling with Release or
+RelWithDebInfo.
+
+BUG: 247483
+REVIEW: 105807
+---
+ CMakeLists.txt | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 7fe4d73..76e4962 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -45,6 +45,14 @@ include(SopranoCPack.cmake)
+ set(QT_MIN_VERSION "4.5.0")
+ find_package(Qt4 REQUIRED)
+ # properly set up compile flags (QT_DEBUG/QT_NO_DEBUG, ...)
++if(CMAKE_BUILD_TYPE)
++    string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_TOLOWER)
++endif()
++
++if (NOT CMAKE_BUILD_TYPE_TOLOWER MATCHES "debug") 
++   add_definitions(-DQT_NO_DEBUG_OUTPUT) 
++endif()
++
+ include(${QT_USE_FILE})
+ 
+ if(NOT SOPRANO_DISABLE_RAPTOR_PARSER OR NOT SOPRANO_DISABLE_RAPTOR_SERIALIZER OR NOT SOPRANO_DISABLE_REDLAND_BACKEND)
+-- 
+1.8.0.2
+
diff --git a/0002-override-QT_USE_FILE-to-fix-include-order.patch b/0002-override-QT_USE_FILE-to-fix-include-order.patch
new file mode 100644
index 0000000..474aea6
--- /dev/null
+++ b/0002-override-QT_USE_FILE-to-fix-include-order.patch
@@ -0,0 +1,39 @@
+From c3e99eebce4232909b5794e9cf201c3ce9cb4917 Mon Sep 17 00:00:00 2001
+From: Patrick Spendrin <ps_ml at gmx.de>
+Date: Wed, 27 Jun 2012 10:47:05 +0200
+Subject: [PATCH 02/10] override QT_USE_FILE to fix include order
+
+this is a workaround for using QT_USE_FILE and having a header
+called plugin.h which collides with same named header file from
+mysql.
+
+Cherry-picked from 5537e71
+---
+ soprano/CMakeLists.txt | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/soprano/CMakeLists.txt b/soprano/CMakeLists.txt
+index 6389e29..28c3188 100644
+--- a/soprano/CMakeLists.txt
++++ b/soprano/CMakeLists.txt
+@@ -1,6 +1,8 @@
+ project(soprano_core)
+ 
+-include_directories(
++# overriding QT_USE_FILE since that includes QT_INCLUDE_DIR before soprano headers
++set(CMAKE_INCLUDE_DIRECTORIES_BEFORE ON)
++include_directories(BEFORE
+   ${soprano_SOURCE_DIR}
+   ${soprano_core_BINARY_DIR}
+   ${soprano_core_SOURCE_DIR}
+@@ -9,6 +11,7 @@ include_directories(
+   ${soprano_core_SOURCE_DIR}/vocabulary
+   ${QT_QTCORE_INCLUDE_DIR}
+   ${QT_INCLUDE_DIR}
++  ${soprano_core_SOURCE_DIR}
+   )
+ 
+ configure_file(soprano-config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/soprano-config.h)
+-- 
+1.8.0.2
+
diff --git a/0003-Fix-100-CPU-usage-when-killing-virtuoso.patch b/0003-Fix-100-CPU-usage-when-killing-virtuoso.patch
new file mode 100644
index 0000000..da3f497
--- /dev/null
+++ b/0003-Fix-100-CPU-usage-when-killing-virtuoso.patch
@@ -0,0 +1,48 @@
+From 418ee0f194564e8734d0f06656316bbbd9623685 Mon Sep 17 00:00:00 2001
+From: David Faure <faure at kde.org>
+Date: Fri, 6 Jul 2012 21:06:45 +0200
+Subject: [PATCH 03/10] Fix 100% CPU usage when killing virtuoso.
+
+read() returned 0 bytes, select() returned "ready", GOTO 10.
+Apparently 0 bytes means "end of file", so error immediately when it happens.
+
+Cherry-picked from 92adb74
+---
+ client/socketstream.cpp | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/client/socketstream.cpp b/client/socketstream.cpp
+index 42645ad..208efaf 100644
+--- a/client/socketstream.cpp
++++ b/client/socketstream.cpp
+@@ -28,7 +28,7 @@
+ #include "literalvalue.h"
+ #include "locator.h"
+ #include "languagetag.h"
+-
++#include <qdebug.h>
+ 
+ Soprano::SocketStream::SocketStream( Soprano::Socket* dev )
+     : m_device( dev )
+@@ -251,13 +251,16 @@ bool Soprano::SocketStream::read( char* data, qint64 size )
+             return false;
+         }
+         else if ( r == 0 && size > 0 ) {
+-            if ( !m_device->waitForReadyRead( 30000 ) ) {
++            // If virtuoso is killed, read returns 0, but select returns ok. This means end of file.
++            // ### TODO: check with Thiago
++            //if ( !m_device->waitForReadyRead( 30000 ) ) {
++            qWarning() << "GOT 0 BYTES -> TIMEOUT";
+                 setError( Error::Error( QString( "Timeout when reading after %1 of %2 bytes (%3)." )
+                                         .arg( cnt )
+                                         .arg( size )
+                                         .arg( m_device->lastError().message() ) ) );
+                 return false;
+-            }
++            //}
+         }
+ 
+         cnt += r;
+-- 
+1.8.0.2
+
diff --git a/0004-Check-return-values-from-write-calls.patch b/0004-Check-return-values-from-write-calls.patch
new file mode 100644
index 0000000..86caab5
--- /dev/null
+++ b/0004-Check-return-values-from-write-calls.patch
@@ -0,0 +1,414 @@
+From 439ae852647ca56f961eefcad6354c7c319eaeb0 Mon Sep 17 00:00:00 2001
+From: David Faure <faure at kde.org>
+Date: Fri, 6 Jul 2012 20:56:28 +0200
+Subject: [PATCH 04/10] Check return values from write calls.
+
+Cherry-picked from adf37c2
+Cherry-picked from 9dc864d
+---
+ client/clientconnection.cpp | 202 ++++++++++++++++++++++++++++++++------------
+ client/socketstream.cpp     |  14 ++-
+ 2 files changed, 152 insertions(+), 64 deletions(-)
+
+diff --git a/client/clientconnection.cpp b/client/clientconnection.cpp
+index 74da78c..febd008 100644
+--- a/client/clientconnection.cpp
++++ b/client/clientconnection.cpp
+@@ -68,6 +68,7 @@ Soprano::Socket *Soprano::Client::ClientConnection::getSocket()
+ 
+ int Soprano::Client::ClientConnection::createModel( const QString& name, const QList<BackendSetting>& settings )
+ {
++    Q_UNUSED( settings );
+     //qDebug() << this << QTime::currentTime().toString( "hh:mm:ss.zzz" ) << QThread::currentThreadId() << "(ClientConnection::createModel)";
+ 
+     Socket* socket = getSocket();
+@@ -75,9 +76,12 @@ int Soprano::Client::ClientConnection::createModel( const QString& name, const Q
+         return 0;
+     SocketStream stream( socket );
+ 
+-    stream.writeUnsignedInt16( COMMAND_CREATE_MODEL );
+-    stream.writeString( name );
+-    Q_UNUSED( settings );
++    if (!stream.writeUnsignedInt16(COMMAND_CREATE_MODEL) ||
++        !stream.writeString(name)) {
++        setError( "Write error", Soprano::Error::ErrorTimeout );
++        socket->close();
++        return 0;
++    }
+ 
+     if ( !socket->waitForReadyRead(s_defaultTimeout) ) {
+         setError( "Command timed out.", Soprano::Error::ErrorTimeout );
+@@ -107,8 +111,12 @@ void Soprano::Client::ClientConnection::removeModel( const QString& name )
+         return;
+     SocketStream stream( socket );
+ 
+-    stream.writeUnsignedInt16( COMMAND_REMOVE_MODEL );
+-    stream.writeString( name );
++    if (!stream.writeUnsignedInt16(COMMAND_REMOVE_MODEL) ||
++        !stream.writeString(name)) {
++        setError( "Write error", Soprano::Error::ErrorTimeout );
++        socket->close();
++        return;
++    }
+ 
+     if ( !socket->waitForReadyRead(s_defaultTimeout) ) {
+         setError( "Command timed out.", Soprano::Error::ErrorTimeout );
+@@ -135,7 +143,11 @@ Soprano::BackendFeatures Soprano::Client::ClientConnection::supportedFeatures()
+         return BackendFeatureNone;
+     SocketStream stream( socket );
+ 
+-    stream.writeUnsignedInt16( COMMAND_SUPPORTED_FEATURES );
++    if (!stream.writeUnsignedInt16(COMMAND_SUPPORTED_FEATURES)) {
++        setError( "Write error", Soprano::Error::ErrorTimeout );
++        socket->close();
++        return 0;
++    }
+ 
+     if ( !socket->waitForReadyRead(s_defaultTimeout) ) {
+         setError( "Command timed out.", Soprano::Error::ErrorTimeout );
+@@ -165,9 +177,13 @@ Soprano::Error::ErrorCode Soprano::Client::ClientConnection::addStatement( int m
+         return Error::convertErrorCode( lastError().code() );
+     SocketStream stream( socket );
+ 
+-    stream.writeUnsignedInt16( COMMAND_MODEL_ADD_STATEMENT );
+-    stream.writeUnsignedInt32( ( quint32 )modelId );
+-    stream.writeStatement( statement );
++    if (!stream.writeUnsignedInt16( COMMAND_MODEL_ADD_STATEMENT ) ||
++        !stream.writeUnsignedInt32( ( quint32 )modelId ) ||
++        !stream.writeStatement(statement)) {
++        setError( "Write error", Soprano::Error::ErrorTimeout );
++        socket->close();
++        return Error::ErrorUnknown;
++    }
+ 
+     if ( !socket->waitForReadyRead(s_defaultTimeout) ) {
+         setError( "Command timed out.", Soprano::Error::ErrorTimeout );
+@@ -196,8 +212,12 @@ int Soprano::Client::ClientConnection::listContexts( int modelId )
+         return 0;
+     SocketStream stream( socket );
+ 
+-    stream.writeUnsignedInt16( COMMAND_MODEL_LIST_CONTEXTS );
+-    stream.writeUnsignedInt32( ( quint32 )modelId );
++    if (!stream.writeUnsignedInt16( COMMAND_MODEL_LIST_CONTEXTS ) ||
++        !stream.writeUnsignedInt32( ( quint32 )modelId ) ) {
++        setError( "Write error", Soprano::Error::ErrorTimeout );
++        socket->close();
++        return 0;
++    }
+ 
+     if ( !socket->waitForReadyRead(s_defaultTimeout) ) {
+         setError( "Command timed out.", Soprano::Error::ErrorTimeout );
+@@ -226,11 +246,15 @@ int Soprano::Client::ClientConnection::executeQuery( int modelId, const QString
+         return 0;
+     SocketStream stream( socket );
+ 
+-    stream.writeUnsignedInt16( COMMAND_MODEL_QUERY );
+-    stream.writeUnsignedInt32( ( quint32 )modelId );
+-    stream.writeString( query );
+-    stream.writeUnsignedInt16( ( quint16 )type );
+-    stream.writeString( userQueryLanguage );
++    if (!stream.writeUnsignedInt16( COMMAND_MODEL_QUERY ) ||
++        !stream.writeUnsignedInt32( ( quint32 )modelId ) ||
++        !stream.writeString( query ) ||
++        !stream.writeUnsignedInt16( ( quint16 )type ) ||
++        !stream.writeString( userQueryLanguage ) ) {
++        setError( "Write error", Soprano::Error::ErrorTimeout );
++        socket->close();
++        return 0;
++    }
+ 
+     if ( !socket->waitForReadyRead(s_defaultTimeout) ) {
+         setError( "Command timed out.", Soprano::Error::ErrorTimeout );
+@@ -259,9 +283,13 @@ int Soprano::Client::ClientConnection::listStatements( int modelId, const Statem
+         return 0;
+     SocketStream stream( socket );
+ 
+-    stream.writeUnsignedInt16( COMMAND_MODEL_LIST_STATEMENTS );
+-    stream.writeUnsignedInt32( ( quint32 )modelId );
+-    stream.writeStatement( partial );
++    if (!stream.writeUnsignedInt16( COMMAND_MODEL_LIST_STATEMENTS ) ||
++        !stream.writeUnsignedInt32( ( quint32 )modelId ) ||
++        !stream.writeStatement( partial ) ) {
++        setError( "Write error", Soprano::Error::ErrorTimeout );
++        socket->close();
++        return 0;
++    }
+ 
+     if ( !socket->waitForReadyRead(s_defaultTimeout) ) {
+         setError( "Command timed out.", Soprano::Error::ErrorTimeout );
+@@ -290,9 +318,13 @@ Soprano::Error::ErrorCode Soprano::Client::ClientConnection::removeAllStatements
+         return Error::convertErrorCode( lastError().code() );
+     SocketStream stream( socket );
+ 
+-    stream.writeUnsignedInt16( COMMAND_MODEL_REMOVE_ALL_STATEMENTS );
+-    stream.writeUnsignedInt32( ( quint32 )modelId );
+-    stream.writeStatement( statement );
++    if (!stream.writeUnsignedInt16( COMMAND_MODEL_REMOVE_ALL_STATEMENTS ) ||
++        !stream.writeUnsignedInt32( ( quint32 )modelId ) ||
++        !stream.writeStatement( statement ) ) {
++        setError( "Write error", Soprano::Error::ErrorTimeout );
++        socket->close();
++        return Error::ErrorUnknown;
++    }
+ 
+     if ( !socket->waitForReadyRead(s_defaultTimeout) ) {
+         setError( "Command timed out.", Soprano::Error::ErrorTimeout );
+@@ -321,9 +353,13 @@ Soprano::Error::ErrorCode Soprano::Client::ClientConnection::removeStatement( in
+         return Error::convertErrorCode( lastError().code() );
+     SocketStream stream( socket );
+ 
+-    stream.writeUnsignedInt16( COMMAND_MODEL_REMOVE_STATEMENT );
+-    stream.writeUnsignedInt32( ( quint32 )modelId );
+-    stream.writeStatement( statement );
++    if (!stream.writeUnsignedInt16( COMMAND_MODEL_REMOVE_STATEMENT ) ||
++        !stream.writeUnsignedInt32( ( quint32 )modelId ) ||
++        !stream.writeStatement( statement ) ) {
++        setError( "Write error", Soprano::Error::ErrorTimeout );
++        socket->close();
++        return Error::ErrorUnknown;
++    }
+ 
+     if ( !socket->waitForReadyRead(s_defaultTimeout) ) {
+         setError( "Command timed out.", Soprano::Error::ErrorTimeout );
+@@ -352,8 +388,12 @@ int Soprano::Client::ClientConnection::statementCount( int modelId )
+         return -1;
+     SocketStream stream( socket );
+ 
+-    stream.writeUnsignedInt16( COMMAND_MODEL_STATEMENT_COUNT );
+-    stream.writeUnsignedInt32( ( quint32 )modelId );
++    if (!stream.writeUnsignedInt16( COMMAND_MODEL_STATEMENT_COUNT ) ||
++        !stream.writeUnsignedInt32( ( quint32 )modelId ) ) {
++        setError( "Write error", Soprano::Error::ErrorTimeout );
++        socket->close();
++        return -1;
++    }
+ 
+     if ( !socket->waitForReadyRead(s_defaultTimeout) ) {
+         setError( "Command timed out.", Soprano::Error::ErrorTimeout );
+@@ -382,9 +422,13 @@ bool Soprano::Client::ClientConnection::containsStatement( int modelId, const St
+         return false;
+     SocketStream stream( socket );
+ 
+-    stream.writeUnsignedInt16( COMMAND_MODEL_CONTAINS_STATEMENT );
+-    stream.writeUnsignedInt32( ( quint32 )modelId );
+-    stream.writeStatement( statement );
++    if (!stream.writeUnsignedInt16( COMMAND_MODEL_CONTAINS_STATEMENT ) ||
++        !stream.writeUnsignedInt32( ( quint32 )modelId ) ||
++        !stream.writeStatement( statement ) ) {
++        setError( "Write error", Soprano::Error::ErrorTimeout );
++        socket->close();
++        return false;
++    }
+ 
+     if ( !socket->waitForReadyRead(s_defaultTimeout) ) {
+         setError( "Command timed out.", Soprano::Error::ErrorTimeout );
+@@ -413,9 +457,13 @@ bool Soprano::Client::ClientConnection::containsAnyStatement( int modelId, const
+         return false;
+     SocketStream stream( socket );
+ 
+-    stream.writeUnsignedInt16( COMMAND_MODEL_CONTAINS_ANY_STATEMENT );
+-    stream.writeUnsignedInt32( ( quint32 )modelId );
+-    stream.writeStatement( statement );
++    if (!stream.writeUnsignedInt16( COMMAND_MODEL_CONTAINS_ANY_STATEMENT ) ||
++        !stream.writeUnsignedInt32( ( quint32 )modelId ) ||
++        !stream.writeStatement( statement ) ) {
++        setError( "Write error", Soprano::Error::ErrorTimeout );
++        socket->close();
++        return false;
++    }
+ 
+     if ( !socket->waitForReadyRead(s_defaultTimeout) ) {
+         setError( "Command timed out.", Soprano::Error::ErrorTimeout );
+@@ -444,8 +492,12 @@ bool Soprano::Client::ClientConnection::isEmpty( int modelId )
+         return false;
+     SocketStream stream( socket );
+ 
+-    stream.writeUnsignedInt16( COMMAND_MODEL_IS_EMPTY );
+-    stream.writeUnsignedInt32( ( quint32 )modelId );
++    if (!stream.writeUnsignedInt16( COMMAND_MODEL_IS_EMPTY ) ||
++        !stream.writeUnsignedInt32( ( quint32 )modelId )) {
++        setError( "Write error", Soprano::Error::ErrorTimeout );
++        socket->close();
++        return false;
++    }
+ 
+     if ( !socket->waitForReadyRead(s_defaultTimeout) ) {
+         setError( "Command timed out.", Soprano::Error::ErrorTimeout );
+@@ -474,8 +526,12 @@ Soprano::Node Soprano::Client::ClientConnection::createBlankNode( int modelId )
+         return Node();
+     SocketStream stream( socket );
+ 
+-    stream.writeUnsignedInt16( COMMAND_MODEL_CREATE_BLANK_NODE );
+-    stream.writeUnsignedInt32( ( quint32 )modelId );
++    if (!stream.writeUnsignedInt16( COMMAND_MODEL_CREATE_BLANK_NODE ) ||
++        !stream.writeUnsignedInt32( ( quint32 )modelId ) ) {
++        setError( "Write error", Soprano::Error::ErrorTimeout );
++        socket->close();
++        return Node();
++    }
+ 
+     if ( !socket->waitForReadyRead(s_defaultTimeout) ) {
+         setError( "Command timed out.", Soprano::Error::ErrorTimeout );
+@@ -504,8 +560,12 @@ bool Soprano::Client::ClientConnection::iteratorNext( int id )
+         return false;
+     SocketStream stream( socket );
+ 
+-    stream.writeUnsignedInt16( COMMAND_ITERATOR_NEXT );
+-    stream.writeUnsignedInt32( ( quint32 )id );
++    if (!stream.writeUnsignedInt16( COMMAND_ITERATOR_NEXT ) ||
++        !stream.writeUnsignedInt32( ( quint32 )id ) ) {
++        setError( "Write error", Soprano::Error::ErrorTimeout );
++        socket->close();
++        return false;
++    }
+ 
+     if ( !socket->waitForReadyRead(s_defaultTimeout) ) {
+         setError( "Command timed out.", Soprano::Error::ErrorTimeout );
+@@ -534,8 +594,12 @@ Soprano::Node Soprano::Client::ClientConnection::nodeIteratorCurrent( int id )
+         return Node();
+     SocketStream stream( socket );
+ 
+-    stream.writeUnsignedInt16( COMMAND_ITERATOR_CURRENT_NODE );
+-    stream.writeUnsignedInt32( ( quint32 )id );
++    if (!stream.writeUnsignedInt16( COMMAND_ITERATOR_CURRENT_NODE ) ||
++        !stream.writeUnsignedInt32( ( quint32 )id ) ) {
++        setError( "Write error", Soprano::Error::ErrorTimeout );
++        socket->close();
++        return Node();
++    }
+ 
+     if ( !socket->waitForReadyRead(s_defaultTimeout) ) {
+         setError( "Command timed out.", Soprano::Error::ErrorTimeout );
+@@ -564,8 +628,12 @@ Soprano::Statement Soprano::Client::ClientConnection::statementIteratorCurrent(
+         return Statement();
+     SocketStream stream( socket );
+ 
+-    stream.writeUnsignedInt16( COMMAND_ITERATOR_CURRENT_STATEMENT );
+-    stream.writeUnsignedInt32( ( quint32 )id );
++    if (!stream.writeUnsignedInt16( COMMAND_ITERATOR_CURRENT_STATEMENT ) ||
++        !stream.writeUnsignedInt32( ( quint32 )id ) ) {
++        setError( "Write error", Soprano::Error::ErrorTimeout );
++        socket->close();
++        return Statement();
++    }
+ 
+     if ( !socket->waitForReadyRead(s_defaultTimeout) ) {
+         setError( "Command timed out.", Soprano::Error::ErrorTimeout );
+@@ -594,8 +662,12 @@ Soprano::BindingSet Soprano::Client::ClientConnection::queryIteratorCurrent( int
+         return BindingSet();
+     SocketStream stream( socket );
+ 
+-    stream.writeUnsignedInt16( COMMAND_ITERATOR_CURRENT_BINDINGSET );
+-    stream.writeUnsignedInt32( ( quint32 )id );
++    if (!stream.writeUnsignedInt16( COMMAND_ITERATOR_CURRENT_BINDINGSET ) ||
++        !stream.writeUnsignedInt32( ( quint32 )id ) ) {
++        setError( "Write error", Soprano::Error::ErrorTimeout );
++        socket->close();
++        return BindingSet();
++    }
+ 
+     if ( !socket->waitForReadyRead(s_defaultTimeout) ) {
+         setError( "Command timed out.", Soprano::Error::ErrorTimeout );
+@@ -624,8 +696,12 @@ Soprano::Statement Soprano::Client::ClientConnection::queryIteratorCurrentStatem
+         return Statement();
+     SocketStream stream( socket );
+ 
+-    stream.writeUnsignedInt16( COMMAND_ITERATOR_CURRENT_STATEMENT );
+-    stream.writeUnsignedInt32( ( quint32 )id );
++    if (!stream.writeUnsignedInt16( COMMAND_ITERATOR_CURRENT_STATEMENT ) ||
++        !stream.writeUnsignedInt32( ( quint32 )id ) ) {
++        setError( "Write error", Soprano::Error::ErrorTimeout );
++        socket->close();
++        return Statement();
++    }
+ 
+     if ( !socket->waitForReadyRead(s_defaultTimeout) ) {
+         setError( "Command timed out.", Soprano::Error::ErrorTimeout );
+@@ -653,8 +729,12 @@ int Soprano::Client::ClientConnection::queryIteratorType( int id )
+         return 0;
+     SocketStream stream( socket );
+ 
+-    stream.writeUnsignedInt16( COMMAND_ITERATOR_QUERY_TYPE );
+-    stream.writeUnsignedInt32( ( quint32 )id );
++    if (!stream.writeUnsignedInt16( COMMAND_ITERATOR_QUERY_TYPE ) ||
++        !stream.writeUnsignedInt32( ( quint32 )id ) ) {
++        setError( "Write error", Soprano::Error::ErrorTimeout );
++        socket->close();
++        return 0;
++    }
+ 
+     if ( !socket->waitForReadyRead(s_defaultTimeout) ) {
+         setError( "Command timed out.", Soprano::Error::ErrorTimeout );
+@@ -683,8 +763,12 @@ bool Soprano::Client::ClientConnection::queryIteratorBoolValue( int id )
+         return false;
+     SocketStream stream( socket );
+ 
+-    stream.writeUnsignedInt16( COMMAND_ITERATOR_QUERY_BOOL_VALUE );
+-    stream.writeUnsignedInt32( ( quint32 )id );
++    if (!stream.writeUnsignedInt16( COMMAND_ITERATOR_QUERY_BOOL_VALUE ) ||
++        !stream.writeUnsignedInt32( ( quint32 )id ) ) {
++        setError( "Write error", Soprano::Error::ErrorTimeout );
++        socket->close();
++        return false;
++    }
+ 
+     if ( !socket->waitForReadyRead(s_defaultTimeout) ) {
+         setError( "Command timed out.", Soprano::Error::ErrorTimeout );
+@@ -712,8 +796,12 @@ void Soprano::Client::ClientConnection::iteratorClose( int id )
+         return;
+     SocketStream stream( socket );
+ 
+-    stream.writeUnsignedInt16( COMMAND_ITERATOR_CLOSE );
+-    stream.writeUnsignedInt32( ( quint32 )id );
++    if (!stream.writeUnsignedInt16( COMMAND_ITERATOR_CLOSE ) ||
++        !stream.writeUnsignedInt32( ( quint32 )id ) ) {
++        setError( "Write error", Soprano::Error::ErrorTimeout );
++        socket->close();
++        return;
++    }
+ 
+     if ( !socket->waitForReadyRead(s_defaultTimeout) ) {
+         setError( "Command timed out.", Soprano::Error::ErrorTimeout );
+@@ -737,8 +825,12 @@ bool Soprano::Client::ClientConnection::checkProtocolVersion()
+         return false;
+     SocketStream stream( socket );
+ 
+-    stream.writeUnsignedInt16( COMMAND_SUPPORTS_PROTOCOL_VERSION );
+-    stream.writeUnsignedInt32( ( quint32 )PROTOCOL_VERSION );
++    if (!stream.writeUnsignedInt16( COMMAND_SUPPORTS_PROTOCOL_VERSION ) ||
++        !stream.writeUnsignedInt32( ( quint32 )PROTOCOL_VERSION ) ) {
++        setError( "Write error", Soprano::Error::ErrorTimeout );
++        socket->close();
++        return false;
++    }
+ 
+     // wait for a reply, but not forever, in case we are connected to something unknown
+     if ( !socket->waitForReadyRead(s_defaultTimeout) ) {
+diff --git a/client/socketstream.cpp b/client/socketstream.cpp
+index 208efaf..7178580 100644
+--- a/client/socketstream.cpp
++++ b/client/socketstream.cpp
+@@ -252,15 +252,11 @@ bool Soprano::SocketStream::read( char* data, qint64 size )
+         }
+         else if ( r == 0 && size > 0 ) {
+             // If virtuoso is killed, read returns 0, but select returns ok. This means end of file.
+-            // ### TODO: check with Thiago
+-            //if ( !m_device->waitForReadyRead( 30000 ) ) {
+-            qWarning() << "GOT 0 BYTES -> TIMEOUT";
+-                setError( Error::Error( QString( "Timeout when reading after %1 of %2 bytes (%3)." )
+-                                        .arg( cnt )
+-                                        .arg( size )
+-                                        .arg( m_device->lastError().message() ) ) );
+-                return false;
+-            //}
++            setError( Error::Error( QString( "Timeout when reading after %1 of %2 bytes (%3)." )
++                                    .arg( cnt )
++                                    .arg( size )
++                                    .arg( m_device->lastError().message() ) ) );
++            return false;
+         }
+ 
+         cnt += r;
+-- 
+1.8.0.2
+
diff --git a/0005-Fix-crashes-due-to-using-the-same-QUrls-in-multiple-.patch b/0005-Fix-crashes-due-to-using-the-same-QUrls-in-multiple-.patch
new file mode 100644
index 0000000..47f26e7
--- /dev/null
+++ b/0005-Fix-crashes-due-to-using-the-same-QUrls-in-multiple-.patch
@@ -0,0 +1,73 @@
+From 4da8fb269a0390c281295b9b11897706c26a0cf2 Mon Sep 17 00:00:00 2001
+From: David Faure <faure at kde.org>
+Date: Thu, 19 Jul 2012 15:17:00 +0200
+Subject: [PATCH 05/10] Fix crashes due to using the same QUrls in multiple
+ threads.
+
+I'm also working on a Qt4 QUrl fix (using QMutex), and this is already
+fixed in Qt5 (the rewrite does no more delayed parsing), but let's make
+our software stable as soon as possible, too, by using QThreadStorage
+to avoid the race.
+
+REVIEW: 105621
+
+Cherry-picked from cf75a01
+---
+ tools/onto2vocabularyclass.cpp | 27 +++++++++++++++++++++++++--
+ 1 file changed, 25 insertions(+), 2 deletions(-)
+
+diff --git a/tools/onto2vocabularyclass.cpp b/tools/onto2vocabularyclass.cpp
+index 9a5a92b..4e77a86 100644
+--- a/tools/onto2vocabularyclass.cpp
++++ b/tools/onto2vocabularyclass.cpp
+@@ -63,6 +63,13 @@ static const char* LGPL_HEADER = "/*\n"
+                                  " * Boston, MA 02110-1301, USA.\n"
+                                  " */\n";
+ 
++#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
++// In Qt4, QUrl is not threadsafe, even for "readonly" concurrent accesses from multiple threads,
++// because the parsing happens on demand, internally in QUrl.
++#define USE_THREAD_STORAGE 1
++#else
++#define USE_THREAD_STORAGE 0
++#endif
+ 
+ #define VERSION "1.2"
+ 
+@@ -435,7 +442,11 @@ int main( int argc, char *argv[] )
+     // write source
+     // ----------------------------------------------------
+     sourceStream << LGPL_HEADER << endl;
+-    sourceStream << "#include \"" << headerFile.fileName() << "\"" << endl << endl;
++    sourceStream << "#include \"" << headerFile.fileName() << "\"" << endl;
++#if USE_THREAD_STORAGE
++    sourceStream << "#include <QThreadStorage>" << endl;
++#endif
++    sourceStream << endl;
+ 
+     QString privateClassName = className[0].toUpper() + className.mid( 1 ).toLower() + "Private";
+     QString singletonName = "s_" + className.toLower();
+@@ -480,7 +491,19 @@ int main( int argc, char *argv[] )
+     }
+     sourceStream << "};" << endl << endl;
+ 
+-    sourceStream << "Q_GLOBAL_STATIC( " << privateClassName << ", " << singletonName << " )" << endl << endl;
++#if USE_THREAD_STORAGE
++    const QString qtsName = "qt" + singletonName;
++    sourceStream << "QThreadStorage<" << privateClassName << " *> " << qtsName << ";" << endl;
++    sourceStream << privateClassName << "* " << singletonName << "()" << endl
++                 << "{" << endl
++                 << createIndent( 1 ) << "if (!" << qtsName << ".hasLocalData())" << endl
++                 << createIndent( 2 ) << qtsName << ".setLocalData(new " << privateClassName << ");" << endl
++                 << createIndent( 1 ) << "return " << qtsName << ".localData();" << endl
++                 << "}" << endl;
++#else
++    sourceStream << "Q_GLOBAL_STATIC( " << privateClassName << ", " << singletonName << " )" << endl;
++#endif
++    sourceStream << endl;
+ 
+     sourceStream << "QUrl ";
+     if ( !namespaceName.isEmpty() ) {
+-- 
+1.8.0.2
+
diff --git a/0006-ErrorCache-Use-QThreadStorage-instead-of-a-QHash-wit.patch b/0006-ErrorCache-Use-QThreadStorage-instead-of-a-QHash-wit.patch
new file mode 100644
index 0000000..b864160
--- /dev/null
+++ b/0006-ErrorCache-Use-QThreadStorage-instead-of-a-QHash-wit.patch
@@ -0,0 +1,75 @@
+From f4d2b9898ff958db1c69ac55fb21677bb6075e24 Mon Sep 17 00:00:00 2001
+From: Vishesh Handa <me at vhanda.in>
+Date: Wed, 1 Aug 2012 17:12:29 +0530
+Subject: [PATCH 06/10] ErrorCache: Use QThreadStorage instead of a QHash with
+ a mutex
+
+We avoid allocating a HashTable since with QThreadStorage, the data is
+stored in the corresponding thread class.
+
+Additionally, with this approach the data is actually deleted when a
+thread is deleted, instead of just lying there for the entire execution
+of the program.
+
+REVIEW: 105812
+---
+ soprano/error.cpp | 15 ++++++---------
+ 1 file changed, 6 insertions(+), 9 deletions(-)
+
+diff --git a/soprano/error.cpp b/soprano/error.cpp
+index bff34dd..12eb454 100644
+--- a/soprano/error.cpp
++++ b/soprano/error.cpp
+@@ -28,6 +28,7 @@
+ #include <QtCore/QMutex>
+ #include <QtCore/QMutexLocker>
+ #include <QtCore/QThread>
++#include <QtCore/QThreadStorage>
+ 
+ 
+ namespace Soprano {
+@@ -186,8 +187,7 @@ Soprano::Error::Locator Soprano::Error::ParserError::locator() const
+ class Soprano::Error::ErrorCache::Private
+ {
+ public:
+-    QHash<QThread*, Error> errorMap;
+-    QMutex errorMapMutex;
++    QThreadStorage<Error> errorStorage;
+ };
+ 
+ 
+@@ -205,8 +205,7 @@ Soprano::Error::ErrorCache::~ErrorCache()
+ 
+ Soprano::Error::Error Soprano::Error::ErrorCache::lastError() const
+ {
+-    QMutexLocker locker( &d->errorMapMutex );
+-    return d->errorMap.value( QThread::currentThread() );
++    return d->errorStorage.localData();
+ }
+ 
+ 
+@@ -218,8 +217,8 @@ void Soprano::Error::ErrorCache::setError( const Error& error ) const
+                       ? QString( "%1(%2)" ).arg( app->applicationFilePath() ).arg( app->applicationPid() )
+                       : QString() )
+                  << "Soprano:" << error;
+-        QMutexLocker locker( &d->errorMapMutex );
+-        d->errorMap[QThread::currentThread()] = error;
++        Q_UNUSED( app ); // when compiled with release mode
++        d->errorStorage.setLocalData( error );
+     }
+     else {
+         clearError();
+@@ -235,9 +234,7 @@ void Soprano::Error::ErrorCache::setError( const QString& errorMessage, int code
+ 
+ void Soprano::Error::ErrorCache::clearError() const
+ {
+-    QMutexLocker locker( &d->errorMapMutex );
+-    if ( !d->errorMap.isEmpty() )
+-        d->errorMap[QThread::currentThread()] = Error();
++    d->errorStorage.setLocalData( Error() );
+ }
+ 
+ 
+-- 
+1.8.0.2
+
diff --git a/0007-Revert-ErrorCache-Use-QThreadStorage-instead-of-a-QH.patch b/0007-Revert-ErrorCache-Use-QThreadStorage-instead-of-a-QH.patch
new file mode 100644
index 0000000..ebad726
--- /dev/null
+++ b/0007-Revert-ErrorCache-Use-QThreadStorage-instead-of-a-QH.patch
@@ -0,0 +1,74 @@
+From c4a0a950d05c7005879e2a086d3911ce28cef1cd Mon Sep 17 00:00:00 2001
+From: Vishesh Handa <me at vhanda.in>
+Date: Wed, 1 Aug 2012 23:23:28 +0530
+Subject: [PATCH 07/10] Revert "ErrorCache: Use QThreadStorage instead of a
+ QHash with a mutex"
+
+This reverts commit f4d2b9898ff958db1c69ac55fb21677bb6075e24.
+
+QThreadStorage are only meant to be used for static variables. This is
+not their intended use case. We get warning every time a QThreadStorage
+is deleted before its thread is deleted. The ErrorCache is used heavily
+in Soprano for small objects such as iterators, and thus we get these
+warnings a lot.
+---
+ soprano/error.cpp | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/soprano/error.cpp b/soprano/error.cpp
+index 12eb454..bff34dd 100644
+--- a/soprano/error.cpp
++++ b/soprano/error.cpp
+@@ -28,7 +28,6 @@
+ #include <QtCore/QMutex>
+ #include <QtCore/QMutexLocker>
+ #include <QtCore/QThread>
+-#include <QtCore/QThreadStorage>
+ 
+ 
+ namespace Soprano {
+@@ -187,7 +186,8 @@ Soprano::Error::Locator Soprano::Error::ParserError::locator() const
+ class Soprano::Error::ErrorCache::Private
+ {
+ public:
+-    QThreadStorage<Error> errorStorage;
++    QHash<QThread*, Error> errorMap;
++    QMutex errorMapMutex;
+ };
+ 
+ 
+@@ -205,7 +205,8 @@ Soprano::Error::ErrorCache::~ErrorCache()
+ 
+ Soprano::Error::Error Soprano::Error::ErrorCache::lastError() const
+ {
+-    return d->errorStorage.localData();
++    QMutexLocker locker( &d->errorMapMutex );
++    return d->errorMap.value( QThread::currentThread() );
+ }
+ 
+ 
+@@ -217,8 +218,8 @@ void Soprano::Error::ErrorCache::setError( const Error& error ) const
+                       ? QString( "%1(%2)" ).arg( app->applicationFilePath() ).arg( app->applicationPid() )
+                       : QString() )
+                  << "Soprano:" << error;
+-        Q_UNUSED( app ); // when compiled with release mode
+-        d->errorStorage.setLocalData( error );
++        QMutexLocker locker( &d->errorMapMutex );
++        d->errorMap[QThread::currentThread()] = error;
+     }
+     else {
+         clearError();
+@@ -234,7 +235,9 @@ void Soprano::Error::ErrorCache::setError( const QString& errorMessage, int code
+ 
+ void Soprano::Error::ErrorCache::clearError() const
+ {
+-    d->errorStorage.setLocalData( Error() );
++    QMutexLocker locker( &d->errorMapMutex );
++    if ( !d->errorMap.isEmpty() )
++        d->errorMap[QThread::currentThread()] = Error();
+ }
+ 
+ 
+-- 
+1.8.0.2
+
diff --git a/0008-Client-Cache-the-current-bindings.patch b/0008-Client-Cache-the-current-bindings.patch
new file mode 100644
index 0000000..25510aa
--- /dev/null
+++ b/0008-Client-Cache-the-current-bindings.patch
@@ -0,0 +1,90 @@
+From f4b1d9413c415871bae256ebb1bc9dee891eee70 Mon Sep 17 00:00:00 2001
+From: Vishesh Handa <me at vhanda.in>
+Date: Mon, 27 Aug 2012 15:45:37 +0530
+Subject: [PATCH 08/10] Client: Cache the current bindings
+
+Cache the current bindings when running the next() in a local variable.
+This way we avoid asking for it during each operator[] and current.
+
+Results in a MASSIVE performance boost - 6 secs vs 1 sec on a large
+query which had a lot of bindings.
+
+REVIEW: 106231
+---
+ client/clientqueryresultiteratorbackend.cpp | 15 ++++++++-------
+ client/clientqueryresultiteratorbackend.h   |  1 +
+ 2 files changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/client/clientqueryresultiteratorbackend.cpp b/client/clientqueryresultiteratorbackend.cpp
+index babbdcc..f3c9fda 100644
+--- a/client/clientqueryresultiteratorbackend.cpp
++++ b/client/clientqueryresultiteratorbackend.cpp
+@@ -45,6 +45,13 @@ bool Soprano::Client::ClientQueryResultIteratorBackend::next()
+     if ( m_model ) {
+         bool r = m_model->client()->iteratorNext( m_iteratorId );
+         setError( m_model->client()->lastError() );
++        if( r ) {
++            m_currentBinding = m_model->client()->queryIteratorCurrent( m_iteratorId );
++            setError( m_model->client()->lastError() );
++        }
++        else {
++            m_currentBinding = Soprano::BindingSet();
++        }
+         return r;
+     }
+     else {
+@@ -57,9 +64,7 @@ bool Soprano::Client::ClientQueryResultIteratorBackend::next()
+ Soprano::BindingSet Soprano::Client::ClientQueryResultIteratorBackend::current() const
+ {
+     if ( m_model ) {
+-        BindingSet s = m_model->client()->queryIteratorCurrent( m_iteratorId );
+-        setError( m_model->client()->lastError() );
+-        return s;
++        return m_currentBinding;
+     }
+     else {
+         setError( "Connection to server closed." );
+@@ -96,28 +101,24 @@ Soprano::Statement Soprano::Client::ClientQueryResultIteratorBackend::currentSta
+ 
+ Soprano::Node Soprano::Client::ClientQueryResultIteratorBackend::binding( const QString &name ) const
+ {
+-    // FIXME: use an extra method for performance
+     return current()[name];
+ }
+ 
+ 
+ Soprano::Node Soprano::Client::ClientQueryResultIteratorBackend::binding( int offset ) const
+ {
+-    // FIXME: use an extra method for performance
+     return current()[offset];
+ }
+ 
+ 
+ int Soprano::Client::ClientQueryResultIteratorBackend::bindingCount() const
+ {
+-    // FIXME: use an extra method for performance
+     return current().count();
+ }
+ 
+ 
+ QStringList Soprano::Client::ClientQueryResultIteratorBackend::bindingNames() const
+ {
+-    // FIXME: use an extra method for performance
+     return current().bindingNames();
+ }
+ 
+diff --git a/client/clientqueryresultiteratorbackend.h b/client/clientqueryresultiteratorbackend.h
+index 2d10756..7e96f3b 100644
+--- a/client/clientqueryresultiteratorbackend.h
++++ b/client/clientqueryresultiteratorbackend.h
+@@ -55,6 +55,7 @@ namespace Soprano
+ 
+         private:
+             int m_iteratorId;
++            BindingSet m_currentBinding;
+             QPointer<ClientModel> m_model;
+         };
+     }
+-- 
+1.8.0.2
+
diff --git a/0009-Optimize-sending-of-LiteralValue-over-the-socket.patch b/0009-Optimize-sending-of-LiteralValue-over-the-socket.patch
new file mode 100644
index 0000000..960b0d9
--- /dev/null
+++ b/0009-Optimize-sending-of-LiteralValue-over-the-socket.patch
@@ -0,0 +1,213 @@
+From 418e7d066b72e08df81204514dba612d589dea22 Mon Sep 17 00:00:00 2001
+From: Vishesh Handa <me at vhanda.in>
+Date: Mon, 27 Aug 2012 15:53:58 +0530
+Subject: [PATCH 09/10] Optimize sending of LiteralValue over the socket
+
+Instead of sending it as <literal-value-string><literal-value-type>.
+Send it as a string/int/bool/whatever when possible, and only send it
+with the full type as a last resort.
+
+This results in code duplication, but that should be fixed by deriving
+both the classes from a common class.
+
+REVIEW: 106233
+---
+ client/socketstream.cpp | 77 ++++++++++++++++++++++++++++++++++++++++++++-----
+ server/datastream.cpp   | 77 ++++++++++++++++++++++++++++++++++++++++++++-----
+ 2 files changed, 140 insertions(+), 14 deletions(-)
+
+diff --git a/client/socketstream.cpp b/client/socketstream.cpp
+index 7178580..36472f1 100644
+--- a/client/socketstream.cpp
++++ b/client/socketstream.cpp
+@@ -177,8 +177,29 @@ bool Soprano::SocketStream::writeLiteralValue( const LiteralValue& value )
+                 writeString( value.language().toString() ) );
+     }
+     else {
+-        return( writeString( value.toString() ) &&
+-                writeUrl( value.dataTypeUri() ) );
++        QVariant var = value.variant();
++        bool status = writeInt32( var.type() );
++        switch( var.type() ) {
++            case QVariant::String:
++                status &= writeString( var.toString() );
++                break;
++            case QVariant::Url:
++                status &= writeUrl( var.toUrl() );
++                break;
++            case QVariant::Int:
++                status &= writeInt32( var.toInt() );
++                break;
++            case QVariant::Bool:
++                status &= writeBool( var.toBool() );
++                break;
++            case QVariant::ByteArray:
++                status &= writeByteArray( var.toByteArray() );
++                break;
++            default:
++                status &= writeString( value.toString() );
++                status &= writeUrl( value.dataTypeUri() );
++        }
++        return status;
+     }
+ }
+ 
+@@ -466,12 +487,54 @@ bool Soprano::SocketStream::readLiteralValue( LiteralValue& val )
+             }
+         }
+         else {
+-            QUrl dt;
+-            if ( readString( v ) &&
+-                 readUrl( dt ) ) {
+-                val = LiteralValue::fromString( v, dt );
+-                return true;
++            int t;
++            bool status = readInt32( t );
++            if( !status )
++                return false;
++
++            QVariant::Type type = static_cast<QVariant::Type>( t );
++            switch( type ) {
++                case QVariant::String: {
++                    QString str;
++                    status &= readString( str );
++                    val = LiteralValue( str );
++                    break;
++                }
++                case QVariant::Url: {
++                    QUrl url;
++                    status &= readUrl( url );
++                    val = LiteralValue( url );
++                    break;
++                }
++                case QVariant::Int: {
++                    int integer;
++                    status &= readInt32( integer );
++                    val = LiteralValue( integer );
++                    break;
++                }
++                case QVariant::Bool: {
++                    bool boolean;
++                    status &= readBool( boolean );
++                    val = LiteralValue( boolean );
++                    break;
++                }
++                case QVariant::ByteArray: {
++                    QByteArray array;
++                    status &= readByteArray( array );
++                    val = LiteralValue( array );
++                    break;
++                }
++                default: {
++                    QString str;
++                    QUrl dt;
++                    status &= readString( str );
++                    status &= readUrl( dt );
++                    val = LiteralValue::fromString( str, dt );
++                    break;
++                }
+             }
++
++            return status;
+         }
+     }
+ 
+diff --git a/server/datastream.cpp b/server/datastream.cpp
+index 17c0c41..f98ee2d 100644
+--- a/server/datastream.cpp
++++ b/server/datastream.cpp
+@@ -177,8 +177,29 @@ bool Soprano::DataStream::writeLiteralValue( const LiteralValue& value )
+                 writeString( value.language().toString() ) );
+     }
+     else {
+-        return( writeString( value.toString() ) &&
+-                writeUrl( value.dataTypeUri() ) );
++        QVariant var = value.variant();
++        bool status = writeInt32( var.type() );
++        switch( var.type() ) {
++            case QVariant::String:
++                status &= writeString( var.toString() );
++                break;
++            case QVariant::Url:
++                status &= writeUrl( var.toUrl() );
++                break;
++            case QVariant::Int:
++                status &= writeInt32( var.toInt() );
++                break;
++            case QVariant::Bool:
++                status &= writeBool( var.toBool() );
++                break;
++            case QVariant::ByteArray:
++                status &= writeByteArray( var.toByteArray() );
++                break;
++            default:
++                status &= writeString( value.toString() );
++                status &= writeUrl( value.dataTypeUri() );
++        }
++        return status;
+     }
+ }
+ 
+@@ -467,12 +488,54 @@ bool Soprano::DataStream::readLiteralValue( LiteralValue& val )
+             }
+         }
+         else {
+-            QUrl dt;
+-            if ( readString( v ) &&
+-                 readUrl( dt ) ) {
+-                val = LiteralValue::fromString( v, dt );
+-                return true;
++            int t;
++            bool status = readInt32( t );
++            if( !status )
++                return false;
++
++            QVariant::Type type = static_cast<QVariant::Type>( t );
++            switch( type ) {
++                case QVariant::String: {
++                    QString str;
++                    status &= readString( str );
++                    val = LiteralValue( str );
++                    break;
++                }
++                case QVariant::Url: {
++                    QUrl url;
++                    status &= readUrl( url );
++                    val = LiteralValue( url );
++                    break;
++                }
++                case QVariant::Int: {
++                    int integer;
++                    status &= readInt32( integer );
++                    val = LiteralValue( integer );
++                    break;
++                }
++                case QVariant::Bool: {
++                    bool boolean;
++                    status &= readBool( boolean );
++                    val = LiteralValue( boolean );
++                    break;
++                }
++                case QVariant::ByteArray: {
++                    QByteArray array;
++                    status &= readByteArray( array );
++                    val = LiteralValue( array );
++                    break;
++                }
++                default: {
++                    QString str;
++                    QUrl dt;
++                    status &= readString( str );
++                    status &= readUrl( dt );
++                    val = LiteralValue::fromString( str, dt );
++                    break;
++                }
+             }
++
++            return status;
+         }
+     }
+ 
+-- 
+1.8.0.2
+
diff --git a/0010-Avoid-crash-on-destruction-of-ClientModel-if-nepomuk.patch b/0010-Avoid-crash-on-destruction-of-ClientModel-if-nepomuk.patch
new file mode 100644
index 0000000..ebfa4e4
--- /dev/null
+++ b/0010-Avoid-crash-on-destruction-of-ClientModel-if-nepomuk.patch
@@ -0,0 +1,30 @@
+From 2122fc9eccefd381db7c830045c4fa65d2bffa63 Mon Sep 17 00:00:00 2001
+From: Simeon Bird <spb at ias.edu>
+Date: Sat, 8 Dec 2012 23:31:23 -0500
+Subject: [PATCH 10/10] Avoid crash on destruction of ClientModel if nepomuk
+ was disabled during the lifetime of the ClientModel.
+
+Crash is also fixed with 690e59e13a applied.
+
+REVIEW: 107639
+BUG: 311222
+---
+ client/clientmodel.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/client/clientmodel.cpp b/client/clientmodel.cpp
+index bdcbed3..4ac406b 100644
+--- a/client/clientmodel.cpp
++++ b/client/clientmodel.cpp
+@@ -50,7 +50,7 @@ Soprano::Client::ClientModel::~ClientModel()
+     // closed by the server anyway.
+     //
+     QMutexLocker locker( &m_openIteratorsMutex );
+-    if ( m_client->isConnected() ) {
++    if ( m_client && m_client->isConnected() ) {
+         for ( int i = 0; i < m_openIterators.count(); ++i ) {
+             m_client->iteratorClose( m_openIterators[i] );
+         }
+-- 
+1.8.0.2
+
diff --git a/soprano.spec b/soprano.spec
index b97b684..b42da1e 100644
--- a/soprano.spec
+++ b/soprano.spec
@@ -6,7 +6,7 @@
 Summary: Qt wrapper API to different RDF storage solutions
 Name:    soprano
 Version: 2.8.0
-Release: 4%{?dist}
+Release: 5%{?dist}
 
 License: LGPLv2+
 URL:     http://sourceforge.net/projects/soprano
@@ -22,6 +22,16 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 ## upstreamable patches
 
 ## upstream patches
+Patch101: 0001-No-qDebug-output-in-non-debug-modes.patch
+Patch102: 0002-override-QT_USE_FILE-to-fix-include-order.patch
+Patch103: 0003-Fix-100-CPU-usage-when-killing-virtuoso.patch
+Patch104: 0004-Check-return-values-from-write-calls.patch
+Patch105: 0005-Fix-crashes-due-to-using-the-same-QUrls-in-multiple-.patch
+Patch106: 0006-ErrorCache-Use-QThreadStorage-instead-of-a-QHash-wit.patch
+Patch107: 0007-Revert-ErrorCache-Use-QThreadStorage-instead-of-a-QH.patch
+Patch108: 0008-Client-Cache-the-current-bindings.patch
+Patch109: 0009-Optimize-sending-of-LiteralValue-over-the-socket.patch
+patch110: 0010-Avoid-crash-on-destruction-of-ClientModel-if-nepomuk.patch
 
 BuildRequires: clucene-core-devel >= 0.9.20-2
 BuildRequires: cmake
@@ -98,13 +108,22 @@ format for easy browsing.
 %setup -q -n soprano-%{version}
 %endif
 
+%patch101 -p1 -b .0001
+%patch102 -p1 -b .0002
+%patch103 -p1 -b .0003
+%patch104 -p1 -b .0004
+%patch105 -p1 -b .0005
+%patch106 -p1 -b .0006
+%patch107 -p1 -b .0007
+%patch108 -p1 -b .0008
+%patch109 -p1 -b .0009
+%patch110 -p1 -b .0010
+
 
 %build
 
 mkdir -p %{_target_platform}
 pushd %{_target_platform}
-# disable copious debug output
-export CXXFLAGS="%{optflags} -DQT_NO_DEBUG_OUTPUT"
 %{cmake} \
   -DDATA_INSTALL_DIR:PATH=%{_kde4_appsdir} \
   -DQT_DOC_DIR=%{?_qt4_docdir}%{!?_qt4_docdir:%(pkg-config --variable=docdir Qt)} \
@@ -203,6 +222,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Mon Dec 24 2012 Rex Dieter <rdieter at fedoraproject.org> 2.8.0-5
+- backport some upstream fixes
+
 * Fri Aug 10 2012 Rex Dieter <rdieter at fedoraproject.org> - 2.8.0-4
 - move virtuoso dep to nepomuk-core
 - remove .spec cruft


More information about the scm-commits mailing list