diff options
author | Jens Lorenz <jlorenz@de.adit-jv.com> | 2018-03-29 16:11:34 +0200 |
---|---|---|
committer | Jens Lorenz <jlorenz@de.adit-jv.com> | 2018-04-09 17:04:42 +0200 |
commit | fff370c2d89acfed702b7c615650706c3c1fadd2 (patch) | |
tree | 37852d4dcccb3ea5a2a2b01b3da25a7b3d3d691c /AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp | |
parent | b487c9b8c5e18797e91a77a4a0b447d63a2a42da (diff) | |
download | audiomanager-fff370c2d89acfed702b7c615650706c3c1fadd2.tar.gz |
AMUtil: Fix startup sequence addFdPoll and removeFdPoll
In case plugins add new fdpoll elements and directly removing them
afterwards the state inside the structure will be changed to REMOVE.
REMOVE will lead all the time to an erase which will not work in case the
pointer is at .end() of vector or the element itself is not the correct
one. Both cases will be fixed just by checking if the fd is the same.
Signed-off-by: Jens Lorenz <jlorenz@de.adit-jv.com>
Diffstat (limited to 'AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp')
-rw-r--r-- | AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp index 085c3b1..a31ccf4 100644 --- a/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp +++ b/AudioManagerUtilities/test/AmSocketHandlerTest/CAmSocketHandlerTest.cpp @@ -30,6 +30,7 @@ #include <fcntl.h> #include <sys/un.h> #include <sys/poll.h> +#include <sys/eventfd.h> #include "CAmDltWrapper.h" #include "CAmSocketHandler.h" @@ -56,6 +57,12 @@ struct TestUserData float f; }; +struct TestStressUserData +{ + CAmSocketHandler &socket; + std::vector<sh_pollHandle_t> &handles; +}; + MockIAmSignalHandler *pMockSignalHandler = NULL; static void signalHandler(int sig, siginfo_t *siginfo, void *context) { @@ -308,6 +315,22 @@ void* threadCallbackUnixSocketAndTimers(void* data) return sendTestData(sock, (struct sockaddr*)&servAddr, sizeof(servAddr), 500000); } +void* threadRaceFd(void* pData) +{ + struct TestStressUserData data = *(struct TestStressUserData*)pData; + usleep(50000); + auto elem = data.handles.begin(); + std::advance(elem, data.handles.size() / 2); + data.socket.removeFDPoll(*elem, sh_rmv_e::RMV_N_CLS); + data.handles.erase(elem); +} +void* threadEnd(void* pData) +{ + struct TestStressUserData data = *(struct TestStressUserData*)pData; + usleep(1000000); + data.socket.exit_mainloop(); +} + TEST(CAmSocketHandlerTest, stressTestUnixSocketAndTimers) { @@ -345,6 +368,58 @@ TEST(CAmSocketHandlerTest, stressTestUnixSocketAndTimers) shutdown(socket_, SHUT_RDWR); } + +TEST(CAmSocketHandlerTest, fdStressTest) +{ + CAmSocketHandler myHandler; + ASSERT_FALSE(myHandler.fatalErrorOccurred()); + + //Check unkonw systemd fd ids + sh_pollHandle_t handle; + EXPECT_EQ(myHandler.addFDPoll(100, 0, NULL, NULL, NULL, NULL, NULL, handle), E_NON_EXISTENT); + + int fd(-1); + std::vector<sh_pollHandle_t> handles(10); + for (auto& hndl : handles) + { + fd = eventfd(0, 0); + ASSERT_EQ(myHandler.addFDPoll(fd, POLL_IN, NULL, NULL, NULL, NULL, NULL, hndl), E_OK); + } + + // remove/add check + ASSERT_EQ(myHandler.addFDPoll(fd, POLL_IN, NULL, NULL, NULL, NULL, NULL, handles.back()), E_ALREADY_EXISTS); + ASSERT_EQ(myHandler.removeFDPoll(handles.back()), E_OK); + ASSERT_EQ(myHandler.addFDPoll(fd, POLL_IN, NULL, NULL, NULL, NULL, NULL, handles.back()), E_OK); + + // create a copy to check if all handles are removed + std::vector<sh_pollHandle_t> handlesCheckup(handles); + + while (handles.size()) + { + pthread_t tid1, tid2; + + // this removes an element before starting the socket handler and we + // erase the last handle + myHandler.removeFDPoll(handles.back(), sh_rmv_e::RMV_N_CLS); + handles.erase(handles.end()-1); + + TestStressUserData data = {myHandler, handles}; + pthread_create(&tid1, NULL, threadEnd, &data); + + // erase the handle in the middle + pthread_create(&tid2, NULL, threadRaceFd, &data); + + myHandler.start_listenting(); + + pthread_join(tid2, NULL); + pthread_join(tid1, NULL); + } + + // now do the check + for (auto& hndl : handlesCheckup) + EXPECT_EQ(myHandler.removeFDPoll(hndl), E_UNKNOWN) << "Handle " << hndl << " not correctly removed before"; +} + TEST(CAmSocketHandlerTest, timersOneshot) { CAmSocketHandler myHandler; |