Fix IPCSuite/WriteTimeout 35/39735/2
authorMateusz Malicki <m.malicki2@samsung.com>
Thu, 21 May 2015 14:12:53 +0000 (16:12 +0200)
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>
Thu, 21 May 2015 16:08:27 +0000 (09:08 -0700)
[Bug]           IPCSuite/WriteTimeout some time fails
[Cause]         To large write timeout and too small response time
                - checking timeout when response has already been
                callSync only sometimes takes into account the serialization time
[Solution]      Increase response time. Wait for sending till timeout countdown start
[Verification]  Build, install on emulator, run IPCSuite/WriteTimeout test (multiple times)

Change-Id: Ic9e814a0ae5cb85a769f0398d5126b0b67f5c626

libs/ipc/internals/processor.hpp
tests/unit_tests/ipc/ut-ipc.cpp
tests/unit_tests/ut.cpp

index ecc3a1d..b1b0a5f 100644 (file)
@@ -442,6 +442,12 @@ private:
     unsigned int mMaxNumberOfPeers;
 
     template<typename SentDataType, typename ReceivedDataType>
+    MessageID callAsyncInternal(const MethodID methodID,
+                                const PeerID peerID,
+                                const std::shared_ptr<SentDataType>& data,
+                                const typename ResultHandler<ReceivedDataType>::type& process);
+
+    template<typename SentDataType, typename ReceivedDataType>
     void setMethodHandlerInternal(const MethodID methodID,
                                   const typename MethodHandler<SentDataType, ReceivedDataType>::type& process);
 
@@ -597,6 +603,15 @@ MessageID Processor::callAsync(const MethodID methodID,
                                const typename ResultHandler<ReceivedDataType>::type& process)
 {
     Lock lock(mStateMutex);
+    return callAsyncInternal<SentDataType, ReceivedDataType>(methodID, peerID, data, process);
+}
+
+template<typename SentDataType, typename ReceivedDataType>
+MessageID Processor::callAsyncInternal(const MethodID methodID,
+                                       const PeerID peerID,
+                                       const std::shared_ptr<SentDataType>& data,
+                                       const typename ResultHandler<ReceivedDataType>::type& process)
+{
     auto request = MethodRequest::create<SentDataType, ReceivedDataType>(methodID, peerID, data, process);
     mRequestQueue.pushBack(Event::METHOD, request);
     return request->messageID;
@@ -618,17 +633,19 @@ std::shared_ptr<ReceivedDataType> Processor::callSync(const MethodID methodID,
         cv.notify_all();
     };
 
-    MessageID messageID = callAsync<SentDataType, ReceivedDataType>(methodID,
-                                                                    peerID,
-                                                                    data,
-                                                                    process);
+    Lock lock(mStateMutex);
+    MessageID messageID = callAsyncInternal<SentDataType, ReceivedDataType>(methodID,
+                                                                            peerID,
+                                                                            data,
+                                                                            process);
 
     auto isResultInitialized = [&result]() {
         return result.isValid();
     };
 
-    Lock lock(mStateMutex);
     LOGT(mLogPrefix + "Waiting for the response...");
+    //In the case of too large sending time response can be received far after timeoutMS but
+    //before this thread wakes up and before predicate check (there will by no timeout exception)
     if (!cv.wait_for(lock, std::chrono::milliseconds(timeoutMS), isResultInitialized)) {
         LOGW(mLogPrefix + "Probably a timeout in callSync. Checking...");
 
index e71a160..958f1f2 100644 (file)
@@ -180,6 +180,15 @@ void longEchoCallback(const PeerID,
     methodResult->set(returnData);
 }
 
+void shortEchoCallback(const PeerID,
+                       std::shared_ptr<RecvData>& data,
+                       MethodResult::Pointer methodResult)
+{
+    std::this_thread::sleep_for(std::chrono::milliseconds(SHORT_OPERATION_TIME));
+    auto returnData = std::make_shared<SendData>(data->intVal);
+    methodResult->set(returnData);
+}
+
 PeerID connect(Service& s, Client& c)
 {
     // Connects the Client to the Service and returns Clients PeerID
@@ -497,7 +506,7 @@ MULTI_FIXTURE_TEST_CASE(ReadTimeout, F, ThreadedFixture, GlibFixture)
 MULTI_FIXTURE_TEST_CASE(WriteTimeout, F, ThreadedFixture, GlibFixture)
 {
     Service s(F::getPoll(), SOCKET_PATH);
-    s.setMethodHandler<SendData, RecvData>(1, echoCallback);
+    s.setMethodHandler<SendData, RecvData>(1, shortEchoCallback);
     s.start();
 
     Client c(F::getPoll(), SOCKET_PATH);
index bb45e84..718bd2c 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <boost/test/included/unit_test.hpp>
 
+#include "utils/signal.hpp"
 
 using namespace boost::unit_test;
 using namespace logger;
@@ -39,5 +40,6 @@ test_suite* init_unit_test_suite(int /*argc*/, char** /*argv*/)
     Logger::setLogLevel(LogLevel::TRACE);
     Logger::setLogBackend(new StderrBackend());
 
+    utils::signalBlock(SIGPIPE);
     return NULL;
 }