From e8f8299849ba238148e1bb9bb5f46424d1d0d888 Mon Sep 17 00:00:00 2001 From: Aleksandar Fabijanic Date: Sat, 25 Nov 2023 15:58:13 -0600 Subject: [PATCH] fix(PollSet): wait on premature epoll_wait return; reinforce tests for windows --- Net/src/PollSet.cpp | 26 ++++++++++++++++++-------- Net/testsuite/src/EchoServer.cpp | 3 ++- Net/testsuite/src/PollSetTest.cpp | 19 ++++++++++++++++--- Net/testsuite/src/SocketTest.cpp | 12 ++++++++---- Net/testsuite/src/SocketTest.h | 8 ++++---- 5 files changed, 48 insertions(+), 20 deletions(-) diff --git a/Net/src/PollSet.cpp b/Net/src/PollSet.cpp index 11bfa487e9..257b2ab679 100644 --- a/Net/src/PollSet.cpp +++ b/Net/src/PollSet.cpp @@ -176,7 +176,11 @@ class PollSetImpl Poco::Timestamp start; rc = epoll_wait(_epollfd, &_events[0], static_cast(_events.size()), static_cast(remainingTime.totalMilliseconds())); - if (rc == 0) return result; + if (rc == 0) + { + if (keepWaiting(start, remainingTime)) continue; + return result; + } // if we are hitting the events limit, resize it; even without resizing, the subseqent // calls would round-robin through the remaining ready sockets, but it's better to give @@ -187,13 +191,7 @@ class PollSetImpl // if interrupted and there's still time left, keep waiting if (SocketImpl::lastError() == POCO_EINTR) { - Poco::Timestamp end; - Poco::Timespan waited = end - start; - if (waited < remainingTime) - { - remainingTime -= waited; - continue; - } + if (keepWaiting(start, remainingTime)) continue; } else SocketImpl::error(); } @@ -304,6 +302,18 @@ class PollSetImpl return epoll_ctl(_epollfd, op, fd, &ev); } + static bool keepWaiting(const Poco::Timestamp& start, Poco::Timespan& remainingTime) + { + Poco::Timestamp end; + Poco::Timespan waited = end - start; + if (waited < remainingTime) + { + remainingTime -= waited; + return true; + } + return false; + } + #ifndef WEPOLL_H_ using EPollHandle = std::atomic; #else // WEPOLL_H_ diff --git a/Net/testsuite/src/EchoServer.cpp b/Net/testsuite/src/EchoServer.cpp index 67f3529c69..48817683f5 100644 --- a/Net/testsuite/src/EchoServer.cpp +++ b/Net/testsuite/src/EchoServer.cpp @@ -83,8 +83,10 @@ void EchoServer::run() { std::cerr << "EchoServer: " << exc.displayText() << std::endl; } + ss.close(); } } + _socket.close(); _done = true; } @@ -99,4 +101,3 @@ bool EchoServer::done() { return _done; } - diff --git a/Net/testsuite/src/PollSetTest.cpp b/Net/testsuite/src/PollSetTest.cpp index 05a3291f48..dd8e0b2517 100644 --- a/Net/testsuite/src/PollSetTest.cpp +++ b/Net/testsuite/src/PollSetTest.cpp @@ -404,9 +404,19 @@ void PollSetTest::testPollClosedServer() "waiting on server after %ds", secs), __LINE__); } } - + char buffer[5]; + int n = ss1.receiveBytes(buffer, sizeof(buffer)); + assertTrue(n == 0); + auto smm = ps.poll(Timespan(1000000)); + assertEqual(1, smm.size()); + assertTrue(ss1 == smm.begin()->first); + ps.remove(ss1); + assertTrue(!ps.empty()); + assertTrue(!ps.has(ss1)); + assertTrue(ps.has(ss2)); echoServer2.stop(); assertTrue (len == ss2.sendBytes(str.data(), len)); + sw.restart(); while (!echoServer2.done()) { Thread::sleep(10); @@ -417,8 +427,11 @@ void PollSetTest::testPollClosedServer() "waiting on server after %ds", secs), __LINE__); } } - - assertEqual(2, ps.poll(Timespan(1000000)).size()); + n = ss2.receiveBytes(buffer, sizeof(buffer)); + assertTrue(n == 0); + smm = ps.poll(Timespan(1000000)); + assertEqual(1, smm.size()); + assertTrue(ss2 == smm.begin()->first); // socket closed or error assertTrue(0 >= ss1.receiveBytes(0, 0)); diff --git a/Net/testsuite/src/SocketTest.cpp b/Net/testsuite/src/SocketTest.cpp index e4df0208b3..c8976a1fb3 100644 --- a/Net/testsuite/src/SocketTest.cpp +++ b/Net/testsuite/src/SocketTest.cpp @@ -562,8 +562,10 @@ void SocketTest::testEchoUnixLocal() if (socketFile.exists()) socketFile.remove(); echoServer.stop(); #else // POCO_HAS_UNIX_SOCKET - #pragma message("[UNIX LOCAL SOCKET DISABLED]") - std::cout << "[UNIX LOCAL SOCKET DISABLED]" << std::endl; + #if POCO_OS == POCO_OS_WINDOWS_NT + #pragma message("[UNIX LOCAL SOCKET DISABLED]") + #endif + std::cout << "[UNIX LOCAL SOCKET DISABLED]"; #endif } @@ -588,8 +590,10 @@ void SocketTest::testUnixLocalAbstract() ss.close(); echoServer.stop(); #else // POCO_HAS_UNIX_SOCKET -#pragma message("[ABSTRACT UNIX LOCAL SOCKET DISABLED]") - std::cout << "[ABSTRACT UNIX LOCAL SOCKET DISABLED]" << std::endl; + #if POCO_OS == POCO_OS_WINDOWS_NT + #pragma message("[ABSTRACT UNIX LOCAL SOCKET DISABLED]") + #endif + std::cout << "[ABSTRACT UNIX LOCAL SOCKET DISABLED]"; #endif } diff --git a/Net/testsuite/src/SocketTest.h b/Net/testsuite/src/SocketTest.h index 7575d7f9df..e3b69e0f69 100644 --- a/Net/testsuite/src/SocketTest.h +++ b/Net/testsuite/src/SocketTest.h @@ -53,10 +53,10 @@ class SocketTest: public CppUnit::TestCase void onReadable(bool& b); void onWritable(bool& b); - int _readableToNot; - int _notToReadable; - int _writableToNot; - int _notToWritable; + int _readableToNot = 0; + int _notToReadable = 0; + int _writableToNot = 0; + int _notToWritable = 0; };