qtmobility/tests/auto/qvaluespacesubscriber/tst_qvaluespacesubscribershared.cpp
changeset 4 90517678cc4f
parent 1 2b40d63a9c3d
child 11 06b8e2af4411
equal deleted inserted replaced
1:2b40d63a9c3d 4:90517678cc4f
    50 #include <QSignalSpy>
    50 #include <QSignalSpy>
    51 #include <QProcess>
    51 #include <QProcess>
    52 #include <QFile>
    52 #include <QFile>
    53 #include <QThread>
    53 #include <QThread>
    54 #include <QTimer>
    54 #include <QTimer>
       
    55 #include <math.h>
    55 
    56 
    56 #include <QDebug>
    57 #include <QDebug>
    57 
    58 
    58 #ifdef Q_OS_WIN
    59 #ifdef Q_OS_WIN
    59 #define _WIN32_WINNT 0x0500
    60 #define _WIN32_WINNT 0x0500
    60 #include <windows.h>
    61 #include <windows.h>
    61 #endif
    62 #endif
    62 
    63 
    63 #define ERROR_SETVALUE_NOT_SUPPORTED 1
    64 #define ERROR_SETVALUE_NOT_SUPPORTED 1
    64 
    65 
    65 #ifdef Q_OS_SYMBIAN
    66 #if defined(Q_OS_SYMBIAN)// || defined (Q_OS_LINUX)
    66     #define QTRY_COMPARE(a,e)                       \
    67     #define QTRY_COMPARE(a,e)                       \
    67         for (int _i = 0; _i < 100; _i++) {          \
    68         for (int _i = 0; _i < 100; _i++) {          \
    68             if ((a) == (e)) break;                  \
    69             if ((a) == (e)) break;                  \
    69             QTest::qWait(1);                        \
    70             QTest::qWait(1);                        \
    70         }                                           \
    71         }                                           \
   456     QFETCH(int, expectedValue);
   457     QFETCH(int, expectedValue);
   457 
   458 
   458     QValueSpaceSubscriber *subscriber = qvariant_cast<QValueSpaceSubscriber*>(testItem);
   459     QValueSpaceSubscriber *subscriber = qvariant_cast<QValueSpaceSubscriber*>(testItem);
   459     QCOMPARE(subscriber->parent(), (QObject*)this);
   460     QCOMPARE(subscriber->parent(), (QObject*)this);
   460     QCOMPARE(subscriber->value(), value);
   461     QCOMPARE(subscriber->value(), value);
   461     #ifdef Q_OS_SYMBIAN
   462     QVERIFY(subscriber->subPaths().toSet().contains(subPaths.toSet()));
   462         QVERIFY(subscriber->subPaths().toSet().contains(subPaths.toSet()));
       
   463     #else
       
   464         QCOMPARE(subscriber->subPaths().toSet(), subPaths.toSet());
       
   465     #endif
       
   466     QCOMPARE(subscriber->path(), path);
   463     QCOMPARE(subscriber->path(), path);
   467     QCOMPARE(subscriber->value(relItemPath, 100).toInt(), expectedValue);
   464     QCOMPARE(subscriber->value(relItemPath, 100).toInt(), expectedValue);
   468 }
   465 }
   469 
   466 
   470 #define ADD(opt, invalid) do {\
   467 #define ADD(opt, invalid) do {\
   527     QStringList homeUserPaths;
   524     QStringList homeUserPaths;
   528     homeUserPaths << "bool" << "int" << "QString" << "QStringList" << "qint64" << "QByteArray"
   525     homeUserPaths << "bool" << "int" << "QString" << "QStringList" << "qint64" << "QByteArray"
   529                   << "double" << "float" << "QChar";
   526                   << "double" << "float" << "QChar";
   530 
   527 
   531     QCOMPARE(subscriber.path(), QLatin1String("/"));
   528     QCOMPARE(subscriber.path(), QLatin1String("/"));
   532     #ifdef Q_OS_SYMBIAN
   529     QVERIFY(subscriber.subPaths().toSet().contains(rootPaths.toSet()));
   533         QVERIFY(subscriber.subPaths().toSet().contains(rootPaths.toSet()));
       
   534     #else
       
   535         QCOMPARE(subscriber.subPaths().toSet(), rootPaths.toSet());
       
   536     #endif
       
   537 
   530 
   538     subscriber.cd("home");
   531     subscriber.cd("home");
   539     QCOMPARE(subscriber.path(), QLatin1String("/home"));
   532     QCOMPARE(subscriber.path(), QLatin1String("/home"));
   540     #ifdef Q_OS_SYMBIAN
   533     QVERIFY(subscriber.subPaths().toSet().contains(homePaths.toSet()));
   541         QVERIFY(subscriber.subPaths().toSet().contains(homePaths.toSet()));
       
   542     #else
       
   543         QCOMPARE(subscriber.subPaths().toSet(), homePaths.toSet());
       
   544     #endif
       
   545 
   534 
   546     subscriber.cd("user");
   535     subscriber.cd("user");
   547     QCOMPARE(subscriber.path(), QLatin1String("/home/user"));
   536     QCOMPARE(subscriber.path(), QLatin1String("/home/user"));
   548     #ifdef Q_OS_SYMBIAN
   537     QVERIFY(subscriber.subPaths().toSet().contains(homeUserPaths.toSet()));
   549         QVERIFY(subscriber.subPaths().toSet().contains(homeUserPaths.toSet()));
       
   550     #else
       
   551         QCOMPARE(subscriber.subPaths().toSet(), homeUserPaths.toSet());
       
   552     #endif
       
   553 
   538 
   554     subscriber.cdUp();
   539     subscriber.cdUp();
   555     QCOMPARE(subscriber.path(), QLatin1String("/home"));
   540     QCOMPARE(subscriber.path(), QLatin1String("/home"));
   556     #ifdef Q_OS_SYMBIAN
   541     QVERIFY(subscriber.subPaths().toSet().contains(homePaths.toSet()));
   557         QVERIFY(subscriber.subPaths().toSet().contains(homePaths.toSet()));
       
   558     #else
       
   559         QCOMPARE(subscriber.subPaths().toSet(), homePaths.toSet());
       
   560     #endif
       
   561 
   542 
   562     subscriber.cd("/home/user");
   543     subscriber.cd("/home/user");
   563     QCOMPARE(subscriber.path(), QLatin1String("/home/user"));
   544     QCOMPARE(subscriber.path(), QLatin1String("/home/user"));
   564     #ifdef Q_OS_SYMBIAN
   545     QVERIFY(subscriber.subPaths().toSet().contains(homeUserPaths.toSet()));
   565         QVERIFY(subscriber.subPaths().toSet().contains(homeUserPaths.toSet()));
       
   566     #else
       
   567         QCOMPARE(subscriber.subPaths().toSet(), homeUserPaths.toSet());
       
   568     #endif
       
   569 }
   546 }
   570 
   547 
   571 void tst_QValueSpaceSubscriber::contentsChanged_data()
   548 void tst_QValueSpaceSubscriber::contentsChanged_data()
   572 {
   549 {
   573     QTest::addColumn<QAbstractValueSpaceLayer *>("layer");
   550     QTest::addColumn<QAbstractValueSpaceLayer *>("layer");
   721     } else {
   698     } else {
   722         spy = new QSignalSpy(&subscriber, SIGNAL(contentsChanged()));
   699         spy = new QSignalSpy(&subscriber, SIGNAL(contentsChanged()));
   723         subscriber.property("value");
   700         subscriber.property("value");
   724     }
   701     }
   725 
   702 
       
   703     #ifdef Q_OS_LINUX
       
   704         //Wait for possible asynchronously emitted signals
       
   705         QEventLoop loop;
       
   706         QTimer::singleShot(100, &loop, SLOT(quit()));
       
   707         loop.exec();
       
   708         spy->clear();
       
   709     #endif
       
   710 
   726     QCOMPARE(spy->count(), 0);
   711     QCOMPARE(spy->count(), 0);
   727 
   712 
   728     busy->setValue("alex/busy", new_value);
   713     busy->setValue("alex/busy", new_value);
   729     busy->sync();
   714     busy->sync();
   730 
   715 
   771     QCOMPARE(base.value("home/user/QString", "default").toString(), QString("testString"));
   756     QCOMPARE(base.value("home/user/QString", "default").toString(), QString("testString"));
   772     QCOMPARE(base.value("home/user/bool", false).toBool(), true);
   757     QCOMPARE(base.value("home/user/bool", false).toBool(), true);
   773     QCOMPARE(base.value("home/user/int", 5).toInt(), 3);
   758     QCOMPARE(base.value("home/user/int", 5).toInt(), 3);
   774     QCOMPARE(base.value("home/user/QByteArray", QByteArray("invalid")).toByteArray(),
   759     QCOMPARE(base.value("home/user/QByteArray", QByteArray("invalid")).toByteArray(),
   775              QByteArray("testByteArray"));
   760              QByteArray("testByteArray"));
   776     QCOMPARE(base.value("home/user/double", 4.0).toDouble(), double(4.56));
   761     QVERIFY(fabs(base.value("home/user/double", 4.0).toDouble() - double(4.56)) < 0.01);
   777     //QCOMPARE(base.value("home/user/float", 4.0).toDouble(), (double)4.56);
   762     //QCOMPARE(base.value("home/user/float", 4.0).toDouble(), (double)4.56);
   778 
   763 
   779     QValueSpaceSubscriber base1(layer->id(), QString("/home"));
   764     QValueSpaceSubscriber base1(layer->id(), QString("/home"));
   780     QCOMPARE(base1.value(QString("usercount"), 5).toInt(), 1);
   765     QCOMPARE(base1.value(QString("usercount"), 5).toInt(), 1);
   781     QCOMPARE(base1.value(QString("user/QString"), "default").toString(), QString("testString"));
   766     QCOMPARE(base1.value(QString("user/QString"), "default").toString(), QString("testString"));
   782     QCOMPARE(base1.value("user/bool", false).toBool(), true);
   767     QCOMPARE(base1.value("user/bool", false).toBool(), true);
   783     QCOMPARE(base1.value("user/int", 5).toInt(), 3);
   768     QCOMPARE(base1.value("user/int", 5).toInt(), 3);
   784     QCOMPARE(base1.value("user/QByteArray", QByteArray("invalid")).toByteArray(),
   769     QCOMPARE(base1.value("user/QByteArray", QByteArray("invalid")).toByteArray(),
   785              QByteArray("testByteArray"));
   770              QByteArray("testByteArray"));
   786     QCOMPARE(base1.value("user/double", 4.0).toDouble(), double(4.56));
   771     QVERIFY(fabs(base.value("home/user/double", 4.0).toDouble() - double(4.56)) < 0.01);
   787     //QCOMPARE(base1.value("user/float", 4.0).toDouble(), double(4.56));
   772     //QCOMPARE(base1.value("user/float", 4.0).toDouble(), double(4.56));
   788 
   773 
   789     QValueSpaceSubscriber base2(layer->id(), QString("/home/user"));
   774     QValueSpaceSubscriber base2(layer->id(), QString("/home/user"));
   790     QCOMPARE(base2.value(QString("usercount"), 5).toInt(), 5);
   775     QCOMPARE(base2.value(QString("usercount"), 5).toInt(), 5);
   791     QCOMPARE(base2.value(QString("QString"), "default").toString(), QString("testString"));
   776     QCOMPARE(base2.value(QString("QString"), "default").toString(), QString("testString"));
   792     QCOMPARE(base2.value("bool", false).toBool(), true);
   777     QCOMPARE(base2.value("bool", false).toBool(), true);
   793     QCOMPARE(base2.value("int", 5).toInt(), 3);
   778     QCOMPARE(base2.value("int", 5).toInt(), 3);
   794     QCOMPARE(base2.value("QByteArray", QByteArray("invalid")).toByteArray(),
   779     QCOMPARE(base2.value("QByteArray", QByteArray("invalid")).toByteArray(),
   795              QByteArray("testByteArray"));
   780              QByteArray("testByteArray"));
   796     QCOMPARE(base2.value("double", 4.0).toDouble(), double(4.56));
   781     QVERIFY(fabs(base.value("home/user/double", 4.0).toDouble() - double(4.56)) < 0.01);
   797     //QCOMPARE(base2.value("float", 4.0).toDouble(), 4.56);
   782     //QCOMPARE(base2.value("float", 4.0).toDouble(), 4.56);
   798 }
   783 }
   799 
   784 
   800 void tst_QValueSpaceSubscriber::ipcTests_data()
   785 void tst_QValueSpaceSubscriber::ipcTests_data()
   801 {
   786 {
   826     QSignalSpy spy(&listener, SIGNAL(baseChanged()));
   811     QSignalSpy spy(&listener, SIGNAL(baseChanged()));
   827     connect(&subscriber, SIGNAL(contentsChanged()), &listener, SIGNAL(baseChanged()));
   812     connect(&subscriber, SIGNAL(contentsChanged()), &listener, SIGNAL(baseChanged()));
   828 
   813 
   829     QProcess process;
   814     QProcess process;
   830     process.setProcessChannelMode(QProcess::ForwardedChannels);
   815     process.setProcessChannelMode(QProcess::ForwardedChannels);
       
   816 #ifdef Q_OS_UNIX
       
   817     process.start("./vsiTestLackey", QStringList() << "-ipcTests" << layer->id().toString());
       
   818 #else
   831     process.start("vsiTestLackey", QStringList() << "-ipcTests" << layer->id().toString());
   819     process.start("vsiTestLackey", QStringList() << "-ipcTests" << layer->id().toString());
       
   820 #endif
   832     QVERIFY(process.waitForStarted());
   821     QVERIFY(process.waitForStarted());
   833 
   822 
   834     //lackey sets value to 100 as part of its startup
   823     //lackey sets value to 100 as part of its startup
   835     QTRY_COMPARE(spy.count(), 1);
   824     QTRY_COMPARE(spy.count(), 1);
   836     QCOMPARE(subscriber.value("", 99).toInt(), 100);
   825     QCOMPARE(subscriber.value("", 99).toInt(), 100);
   898     QSignalSpy changeSpy(&listener, SIGNAL(baseChanged()));
   887     QSignalSpy changeSpy(&listener, SIGNAL(baseChanged()));
   899     QObject::connect(&subscriber, SIGNAL(contentsChanged()), &listener, SIGNAL(baseChanged()));
   888     QObject::connect(&subscriber, SIGNAL(contentsChanged()), &listener, SIGNAL(baseChanged()));
   900 
   889 
   901     QProcess process;
   890     QProcess process;
   902     process.setProcessChannelMode(QProcess::ForwardedChannels);
   891     process.setProcessChannelMode(QProcess::ForwardedChannels);
       
   892 #ifdef Q_OS_UNIX
       
   893     process.start("./vsiTestLackey", QStringList() << "-ipcRemoveKey" << layer->id().toString());
       
   894 #else
   903     process.start("vsiTestLackey", QStringList() << "-ipcRemoveKey" << layer->id().toString());
   895     process.start("vsiTestLackey", QStringList() << "-ipcRemoveKey" << layer->id().toString());
       
   896 #endif
   904     QVERIFY(process.waitForStarted());
   897     QVERIFY(process.waitForStarted());
   905 
   898 
   906     // Wait for lackey to create "value".
   899     // Wait for lackey to create "value".
   907     QTRY_COMPARE(changeSpy.count(), 1);
   900     QTRY_COMPARE(changeSpy.count(), 1);
   908     QCOMPARE(subscriber.value("value", 5).toInt(), 100);
   901     QCOMPARE(subscriber.value("value", 5).toInt(), 100);
  1039     // Lackey is not running, so value will not exist.
  1032     // Lackey is not running, so value will not exist.
  1040     QCOMPARE(subscriber->value(QString(), 10).toInt(), 10);
  1033     QCOMPARE(subscriber->value(QString(), 10).toInt(), 10);
  1041 
  1034 
  1042     QProcess process;
  1035     QProcess process;
  1043     process.setProcessChannelMode(QProcess::ForwardedChannels);
  1036     process.setProcessChannelMode(QProcess::ForwardedChannels);
       
  1037 #ifdef Q_OS_UNIX
       
  1038     process.start("./vsiTestLackey", QStringList()
       
  1039         << "-ipcInterestNotification" << layer->id().toString());
       
  1040 #else
  1044     process.start("vsiTestLackey", QStringList()
  1041     process.start("vsiTestLackey", QStringList()
  1045         << "-ipcInterestNotification" << layer->id().toString());
  1042         << "-ipcInterestNotification" << layer->id().toString());
       
  1043 #endif
  1046     QVERIFY(process.waitForStarted());
  1044     QVERIFY(process.waitForStarted());
  1047 
  1045 
  1048     // Lackey will receive interestChanged from server and set the attribute.
  1046     // Lackey will receive interestChanged from server and set the attribute.
  1049     QTRY_COMPARE(changeSpy.count(), 1);
  1047     QTRY_COMPARE(changeSpy.count(), 1);
  1050     changeSpy.clear();
  1048     changeSpy.clear();
  1078 class WriteThread : public QThread
  1076 class WriteThread : public QThread
  1079 {
  1077 {
  1080     Q_OBJECT
  1078     Q_OBJECT
  1081 
  1079 
  1082 public:
  1080 public:
  1083     WriteThread();
  1081     WriteThread(const QUuid& layerId);
  1084 
  1082 
  1085     void setDone();
  1083     void setDone();
  1086 
  1084 
  1087 protected:
  1085 protected:
  1088     void run();
  1086     void run();
  1089 
  1087 
  1090 private:
  1088 private:
  1091     QValueSpacePublisher *publisher;
  1089     QValueSpacePublisher *publisher;
  1092     bool done;
  1090     bool done;
       
  1091     const QUuid& layerId;
  1093 };
  1092 };
  1094 
  1093 
  1095 WriteThread::WriteThread()
  1094 WriteThread::WriteThread(const QUuid& layerId)
  1096 :   publisher(0), done(false)
  1095 :   publisher(0), done(false), layerId(layerId)
  1097 {
  1096 {
  1098 }
  1097 }
  1099 
  1098 
  1100 void WriteThread::setDone()
  1099 void WriteThread::setDone()
  1101 {
  1100 {
  1104 
  1103 
  1105 void WriteThread::run()
  1104 void WriteThread::run()
  1106 {
  1105 {
  1107     QTest::qWait(100);  // give some ReadThreads some time to start.
  1106     QTest::qWait(100);  // give some ReadThreads some time to start.
  1108 
  1107 
  1109     QValueSpacePublisher publisher("/threads");
  1108     QValueSpacePublisher publisher(layerId, "/threads");
  1110 
  1109 
  1111     uint value = 0;
  1110     uint value = 0;
  1112     while (!done) {
  1111     while (!done) {
  1113         publisher.setValue("value", value);
  1112         publisher.setValue("value", value);
  1114         publisher.sync();
  1113         publisher.sync();
  1120 class ReadThread : public QThread
  1119 class ReadThread : public QThread
  1121 {
  1120 {
  1122     Q_OBJECT
  1121     Q_OBJECT
  1123 
  1122 
  1124 public:
  1123 public:
  1125     ReadThread(QValueSpaceSubscriber *subscriber, bool sync);
  1124     ReadThread(QValueSpaceSubscriber *subscriber, bool sync, const QUuid& layerId);
  1126 
  1125 
  1127 protected:
  1126 protected:
  1128     void run();
  1127     void run();
  1129 
  1128 
  1130 private:
  1129 private:
  1131     QValueSpaceSubscriber *masterSubscriber;
  1130     QValueSpaceSubscriber *masterSubscriber;
  1132     int iterations;
  1131     int iterations;
  1133     bool synchronised;
  1132     bool synchronised;
       
  1133     const QUuid& layerId;
  1134 };
  1134 };
  1135 
  1135 
  1136 ReadThread::ReadThread(QValueSpaceSubscriber *subscriber, bool sync)
  1136 ReadThread::ReadThread(QValueSpaceSubscriber *subscriber, bool sync, const QUuid& layerId)
  1137 :   masterSubscriber(subscriber), iterations(0), synchronised(sync)
  1137 :   masterSubscriber(subscriber), iterations(0), synchronised(sync), layerId(layerId)
  1138 {
  1138 {
  1139 }
  1139 }
  1140 
  1140 
  1141 void ReadThread::run()
  1141 void ReadThread::run()
  1142 {
  1142 {
  1143     while (true) {
  1143     while (true) {
  1144         QValueSpaceSubscriber subscriber;
  1144         QValueSpaceSubscriber subscriber(layerId, masterSubscriber->path());
  1145         subscriber.setPath(masterSubscriber);
       
  1146 
  1145 
  1147         if (synchronised) {
  1146         if (synchronised) {
  1148             QEventLoop loop;
  1147             QEventLoop loop;
  1149             connect(&subscriber, SIGNAL(contentsChanged()), &loop, SLOT(quit()));
  1148             connect(&subscriber, SIGNAL(contentsChanged()), &loop, SLOT(quit()));
  1150             QTimer::singleShot(1000, &loop, SLOT(quit()));
  1149             QTimer::singleShot(1000, &loop, SLOT(quit()));
  1161 
  1160 
  1162 void tst_QValueSpaceSubscriber::threads_data()
  1161 void tst_QValueSpaceSubscriber::threads_data()
  1163 {
  1162 {
  1164     QTest::addColumn<unsigned int>("threads");
  1163     QTest::addColumn<unsigned int>("threads");
  1165     QTest::addColumn<bool>("synchronised");
  1164     QTest::addColumn<bool>("synchronised");
  1166 
  1165     QTest::addColumn<QUuid>("layerId");
  1167     QTest::newRow("1 thread") << uint(1) << true;
  1166 
  1168     QTest::newRow("2 threads") << uint(2) << true;
  1167     QList<QAbstractValueSpaceLayer *> layers = QValueSpaceManager::instance()->getLayers();
       
  1168 
       
  1169     int foundLayers = 0;
       
  1170     for (int i = 0; i < layers.count(); ++i) {
       
  1171         QAbstractValueSpaceLayer *layer = layers.at(i);
       
  1172 
       
  1173         //GConfLayer can't provide thread-safety because it eventually depends on
       
  1174         //DBus which isn't fully thread-safe
       
  1175         if (layer->id() == QVALUESPACE_GCONF_LAYER) {
       
  1176             continue;
       
  1177         }
       
  1178 
       
  1179         const QUuid id = layer->id();
       
  1180 
       
  1181         QTest::newRow("1 thread") << uint(1) << true << id;
       
  1182         QTest::newRow("2 threads") << uint(2) << true << id;
  1169 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
  1183 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
  1170     QTest::newRow("10 threads") << uint(10) << true;
  1184         QTest::newRow("10 threads") << uint(10) << true << id;
  1171 #else
  1185 #else
  1172     QTest::newRow("100 threads") << uint(100) << true;
  1186         QTest::newRow("100 threads") << uint(100) << true << id;
  1173 #endif
  1187 #endif
  1174     QTest::newRow("1 thread, unsynchronised") << uint(1) << false;
  1188         QTest::newRow("1 thread, unsynchronised") << uint(1) << false << id;
  1175     QTest::newRow("2 threads, unsynchronised") << uint(2) << false;
  1189         QTest::newRow("2 threads, unsynchronised") << uint(2) << false << id;
  1176 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
  1190 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
  1177     QTest::newRow("10 threads") << uint(10) << false;
  1191         QTest::newRow("10 threads") << uint(10) << false  << id;
  1178 #else
  1192 #else
  1179     QTest::newRow("100 threads, unsynchronised") << uint(100) << false;
  1193         QTest::newRow("100 threads, unsynchronised") << uint(100) << false << id;
  1180 #endif
  1194 #endif
       
  1195         foundLayers++;
       
  1196     }
       
  1197 
       
  1198     if (foundLayers == 0)
       
  1199         QSKIP("No layers providing thread-safety found", SkipAll);
  1181 }
  1200 }
  1182 
  1201 
  1183 void tst_QValueSpaceSubscriber::threads()
  1202 void tst_QValueSpaceSubscriber::threads()
  1184 {
  1203 {
  1185     QFETCH(unsigned int, threads);
  1204     QFETCH(unsigned int, threads);
  1186     QFETCH(bool, synchronised);
  1205     QFETCH(bool, synchronised);
       
  1206     QFETCH(QUuid, layerId);
  1187 
  1207 
  1188     QEventLoop writeLoop;
  1208     QEventLoop writeLoop;
  1189     WriteThread *writeThread = new WriteThread;
  1209     WriteThread *writeThread = new WriteThread(layerId);
  1190     connect(writeThread, SIGNAL(finished()), &writeLoop, SLOT(quit()));
  1210     connect(writeThread, SIGNAL(finished()), &writeLoop, SLOT(quit()));
  1191     writeThread->start();
  1211     writeThread->start();
  1192 
  1212 
  1193     QValueSpaceSubscriber masterSubscriber("/threads/value");
  1213     QValueSpaceSubscriber masterSubscriber(layerId, "/threads/value");
  1194 
  1214 
  1195     QVector<ReadThread *> readThreads(threads);
  1215     QVector<ReadThread *> readThreads(threads);
  1196 
  1216 
  1197     for (unsigned int i = 0; i < threads; ++i) {
  1217     for (unsigned int i = 0; i < threads; ++i) {
  1198         readThreads[i] = new ReadThread(&masterSubscriber, synchronised);
  1218         readThreads[i] = new ReadThread(&masterSubscriber, synchronised, layerId);
  1199         readThreads[i]->start();
  1219         readThreads[i]->start();
  1200     }
  1220     }
  1201 
  1221 
  1202     for (unsigned int i = 0; i < threads; ++i) {
  1222     for (unsigned int i = 0; i < threads; ++i) {
  1203         QEventLoop loop;
  1223         QEventLoop loop;
  1212 
  1232 
  1213     if (!writeThread->isFinished())
  1233     if (!writeThread->isFinished())
  1214         writeLoop.exec();
  1234         writeLoop.exec();
  1215 
  1235 
  1216     delete writeThread;
  1236     delete writeThread;
  1217     #ifdef Q_OS_SYMBIAN
  1237 #ifdef Q_OS_SYMBIAN
  1218         QValueSpacePublisher resetPublisher("/threads");
  1238     QValueSpacePublisher resetPublisher(layerId, "/threads");
  1219         resetPublisher.resetValue("value");
  1239     resetPublisher.resetValue("value");
  1220     #endif
  1240 #endif
  1221 
  1241 
  1222 }
  1242 }
  1223 
  1243 
  1224 #include "tst_qvaluespacesubscribershared.moc"
  1244 #include "tst_qvaluespacesubscribershared.moc"