From 13d3aa32753860aa97f66d5641c81b0d00c83ae5 Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Thu, 21 May 2015 16:12:53 +0200 Subject: [PATCH] Fix IPCSuite/WriteTimeout [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 | 27 ++++++++++++++++++++++----- tests/unit_tests/ipc/ut-ipc.cpp | 11 ++++++++++- tests/unit_tests/ut.cpp | 2 ++ 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/libs/ipc/internals/processor.hpp b/libs/ipc/internals/processor.hpp index ecc3a1d..b1b0a5f 100644 --- a/libs/ipc/internals/processor.hpp +++ b/libs/ipc/internals/processor.hpp @@ -442,6 +442,12 @@ private: unsigned int mMaxNumberOfPeers; template + MessageID callAsyncInternal(const MethodID methodID, + const PeerID peerID, + const std::shared_ptr& data, + const typename ResultHandler::type& process); + + template void setMethodHandlerInternal(const MethodID methodID, const typename MethodHandler::type& process); @@ -597,6 +603,15 @@ MessageID Processor::callAsync(const MethodID methodID, const typename ResultHandler::type& process) { Lock lock(mStateMutex); + return callAsyncInternal(methodID, peerID, data, process); +} + +template +MessageID Processor::callAsyncInternal(const MethodID methodID, + const PeerID peerID, + const std::shared_ptr& data, + const typename ResultHandler::type& process) +{ auto request = MethodRequest::create(methodID, peerID, data, process); mRequestQueue.pushBack(Event::METHOD, request); return request->messageID; @@ -618,17 +633,19 @@ std::shared_ptr Processor::callSync(const MethodID methodID, cv.notify_all(); }; - MessageID messageID = callAsync(methodID, - peerID, - data, - process); + Lock lock(mStateMutex); + MessageID messageID = callAsyncInternal(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..."); diff --git a/tests/unit_tests/ipc/ut-ipc.cpp b/tests/unit_tests/ipc/ut-ipc.cpp index e71a160..958f1f2 100644 --- a/tests/unit_tests/ipc/ut-ipc.cpp +++ b/tests/unit_tests/ipc/ut-ipc.cpp @@ -180,6 +180,15 @@ void longEchoCallback(const PeerID, methodResult->set(returnData); } +void shortEchoCallback(const PeerID, + std::shared_ptr& data, + MethodResult::Pointer methodResult) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(SHORT_OPERATION_TIME)); + auto returnData = std::make_shared(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(1, echoCallback); + s.setMethodHandler(1, shortEchoCallback); s.start(); Client c(F::getPoll(), SOCKET_PATH); diff --git a/tests/unit_tests/ut.cpp b/tests/unit_tests/ut.cpp index bb45e84..718bd2c 100644 --- a/tests/unit_tests/ut.cpp +++ b/tests/unit_tests/ut.cpp @@ -30,6 +30,7 @@ #include +#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; } -- 2.7.4