[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [dferry] tests/buslogic: Several improvements to multithreading test.
From:       Andreas Hartmetz <ahartmetz () gmail ! com>
Date:       2015-12-31 14:23:50
Message-ID: E1aEe8s-0003kS-2w () scm ! kde ! org
[Download RAW message or body]

Git commit 9dc434bc5d82fc71779f32cf74011ee9e210a4d0 by Andreas Hartmetz.
Committed on 31/12/2015 at 14:22.
Pushed by ahartmetz into branch 'master'.

Several improvements to multithreading test.

- make it more verbose
- better naming
- more comments

This helped with the initial Windows port.

M  +36   -24   tests/buslogic/tst_threads.cpp

http://commits.kde.org/dferry/9dc434bc5d82fc71779f32cf74011ee9e210a4d0

diff --git a/tests/buslogic/tst_threads.cpp b/tests/buslogic/tst_threads.cpp
index a99c7aa..f350016 100644
--- a/tests/buslogic/tst_threads.cpp
+++ b/tests/buslogic/tst_threads.cpp
@@ -27,6 +27,7 @@
 #include "imessagereceiver.h"
 #include "message.h"
 #include "pendingreply.h"
+#include "stringtools.h"
 #include "transceiver.h"
 
 #include "../testutil.h"
@@ -41,10 +42,12 @@ static const char *echoPath = "/echo";
 static const char *echoInterface = "org.example_fb39a8dbd0aa66d2.echo";
 static const char *echoMethod = "echo";
 
+//////////////// Multi-thread ping-pong test ////////////////
+
 static const char *pingPayload = "-> J. Random PING";
 static const char *pongPayload = "<- J. Random Pong";
 
-class PingResponder : public IMessageReceiver
+class PongSender : public IMessageReceiver
 {
 public:
     Transceiver *m_transceiver;
@@ -71,6 +74,7 @@ public:
             writer.writeString(pongPayload);
             pong.setArguments(writer.finish());
 
+            std::cout << "\n\nSending pong!\n\n";
             Error replyError = m_transceiver->sendNoReply(std::move(pong));
             TEST(!replyError.isError());
 
@@ -79,30 +83,33 @@ public:
     }
 };
 
-static void pongThreadRun(Transceiver::CommRef primary, std::atomic<bool> \
*secondaryReady) +static void pongThreadRun(Transceiver::CommRef mainTransceiverRef, \
std::atomic<bool> *pongThreadReady)  {
-    // open a Transceiver "slaved" to the other Transceiver - it has its own event \
                loop, but uses
-    // the same connection as the other Transceiver
-    std::cout << " Other thread starting!\n";
+    std::cout << " Pong thread starting!\n";
     EventDispatcher eventDispatcher;
-    Transceiver trans(&eventDispatcher, std::move(primary));
+    Transceiver trans(&eventDispatcher, std::move(mainTransceiverRef));
 
-    PingResponder responder;
-    responder.m_transceiver = &trans;
+    PongSender pongSender;
+    pongSender.m_transceiver = &trans;
 
-    trans.setSpontaneousMessageReceiver(&responder);
+    trans.setSpontaneousMessageReceiver(&pongSender);
 
     while (eventDispatcher.poll()) {
+        std::cout << " Pong thread waking up!\n";
         if (trans.uniqueName().length()) {
-            *secondaryReady = true;
+            pongThreadReady->store(true);
             // HACK: we do this only to wake up the main thread's event loop
+            std::cout << "\n\nSending WAKEUP package!!\n\n";
             Message wakey = Message::createCall(echoPath, "org.notexample.foo", \
echoMethod);  wakey.setDestination(trans.uniqueName());
             trans.sendNoReply(std::move(wakey));
+        } else {
+            std::cout << " Pong thread: NO NAME YET!\n";
         }
         // receive ping message
         // send pong message
     }
+    std::cout << " Pong thread almost finished!\n";
 }
 
 class PongReceiver : public IMessageReceiver
@@ -115,11 +122,10 @@ public:
 
         Arguments args = pong.arguments();
         Arguments::Reader reader(args);
-        // cstring payload = reader.readString();
-        reader.readString();
+        std::string strPayload = toStdString(reader.readString());
         TEST(!reader.error().isError());
         TEST(reader.isFinished());
-        // TEST(payload == pongPayload);
+        TEST(strPayload == pongPayload);
     }
 };
 
@@ -128,8 +134,8 @@ static void testPingPong()
     EventDispatcher eventDispatcher;
     Transceiver trans(&eventDispatcher, ConnectionInfo::Bus::Session);
 
-    std::atomic<bool> secondaryReady(false);
-    std::thread pongThread(pongThreadRun, trans.createCommRef(), &secondaryReady);
+    std::atomic<bool> pongThreadReady(false);
+    std::thread pongThread(pongThreadRun, trans.createCommRef(), &pongThreadReady);
 
     // finish creating the connection
     while (trans.uniqueName().empty()) {
@@ -152,7 +158,8 @@ static void testPingPong()
     bool sentPing = false;
     while (!sentPing || !pongReply.isFinished()) {
         eventDispatcher.poll();
-        if (secondaryReady && !sentPing) {
+        if (pongThreadReady.load() && !sentPing) {
+            std::cout << "\n\nSending ping!!\n\n";
             pongReply = trans.send(std::move(ping));
             pongReply.setReceiver(&pongReceiver);
             sentPing = true;
@@ -165,6 +172,8 @@ static void testPingPong()
     pongThread.join();
 }
 
+//////////////// Multi-threaded timeout test ////////////////
+
 class TimeoutReceiver : public IMessageReceiver
 {
 public:
@@ -177,25 +186,28 @@ public:
     }
 };
 
-static void timeoutThreadRun(Transceiver::CommRef primary, std::atomic<bool> *done)
+static void timeoutThreadRun(Transceiver::CommRef mainTransceiverRef, \
std::atomic<bool> *done)  {
-    // open a Transceiver "slaved" to the other Transceiver - it has its own event \
                loop, but uses
-    // the same connection as the other Transceiver
+    // TODO v turn this into proper documentation in Transceiver
+    // Open a Transceiver "slaved" to the other Transceiver - it runs its own event \
loop in this thread +    // and has message I/O handled by the Transceiver in the \
"master" thread through message passing. +    // The main purpose of that is to use \
just one DBus connection per application( module), which is often +    // more \
convenient for client programmers and brings some limited ordering guarantees.  \
std::cout << " Other thread starting!\n";  EventDispatcher eventDispatcher;
-    Transceiver trans(&eventDispatcher, std::move(primary));
+    Transceiver trans(&eventDispatcher, std::move(mainTransceiverRef));
     while (!trans.uniqueName().length()) {
         eventDispatcher.poll();
     }
 
     Message notRepliedTo = Message::createCall(echoPath, echoInterface, echoMethod);
-
     notRepliedTo.setDestination(trans.uniqueName());
-    PendingReply neverGonnaReply = trans.send(std::move(notRepliedTo), 50);
+
+    PendingReply deadReply = trans.send(std::move(notRepliedTo), 50);
     TimeoutReceiver timeoutReceiver;
-    neverGonnaReply.setReceiver(&timeoutReceiver);
+    deadReply.setReceiver(&timeoutReceiver);
 
-    while (!neverGonnaReply.isFinished()) {
+    while (!deadReply.isFinished()) {
         eventDispatcher.poll();
     }
     *done = true;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic