net/ServerSocket.hpp | 3 +- net/Socket.cpp | 20 ++++++++------ net/Socket.hpp | 70 ++++++++++++++++++++++++++------------------------- 3 files changed, 50 insertions(+), 43 deletions(-)
New commits: commit 3a5ca4b03ffbd8e0428a2bc3fa325f1f76ba1feb Author: Michael Meeks <[email protected]> Date: Fri Mar 17 20:51:45 2017 +0000 Switch to std::chrono from Poco::Time and simplify lots. diff --git a/net/ServerSocket.hpp b/net/ServerSocket.hpp index 33d01e31..a5112233 100644 --- a/net/ServerSocket.hpp +++ b/net/ServerSocket.hpp @@ -87,7 +87,8 @@ public: void dumpState(std::ostream& os) override; - HandleResult handlePoll(const Poco::Timestamp &/* now */, int events) override + HandleResult handlePoll(std::chrono::steady_clock::time_point /* now */, + int events) override { if (events & POLLIN) { diff --git a/net/Socket.hpp b/net/Socket.hpp index 79ad57e4..3aaa3d52 100644 --- a/net/Socket.hpp +++ b/net/Socket.hpp @@ -29,9 +29,8 @@ #include <mutex> #include <sstream> #include <thread> +#include <chrono> -#include <Poco/Timespan.h> -#include <Poco/Timestamp.h> #include <Poco/Net/HTTPResponse.h> #include "Common.hpp" @@ -77,11 +76,12 @@ public: virtual int getPollEvents() = 0; /// Contract the poll timeout to match our needs - virtual void updateTimeout(Poco::Timestamp &/*timeout*/) { /* do nothing */ } + virtual void updateTimeout(std::chrono::steady_clock::time_point /* now */, + int & /* timeoutMaxMs */) { /* do nothing */ } /// Handle results of events returned from poll enum class HandleResult { CONTINUE, SOCKET_CLOSED }; - virtual HandleResult handlePoll(const Poco::Timestamp &now, int events) = 0; + virtual HandleResult handlePoll(std::chrono::steady_clock::time_point now, int events) = 0; /// manage latency issues around packet aggregation void setNoDelay(bool noDelay = true) @@ -291,29 +291,29 @@ public: } /// Poll the sockets for available data to read or buffer to write. - void poll(const int timeoutMaxMs) + void poll(int timeoutMaxMs) { assert(isCorrectThread()); - Poco::Timestamp now; - Poco::Timestamp timeout = now; - timeout += Poco::Timespan(0 /* s */, timeoutMaxMs * 1000 /* us */); + std::chrono::steady_clock::time_point now = + std::chrono::steady_clock::now(); // The events to poll on change each spin of the loop. - setupPollFds(timeout); + setupPollFds(now, timeoutMaxMs); const size_t size = _pollSockets.size(); int rc; do { - rc = ::poll(&_pollFds[0], size + 1, (timeout - now)/1000); + rc = ::poll(&_pollFds[0], size + 1, timeoutMaxMs); } while (rc < 0 && errno == EINTR); - LOG_TRC("Poll completed with " << rc << " live polls " - << ((rc==0) ? "(timeout)" : "")); + LOG_TRC("Poll completed with " << rc << " live polls max (" << timeoutMaxMs << "ms)" + << ((rc==0) ? "(timedout)" : "")); // Fire the callback and remove dead fds. - Poco::Timestamp newNow; + std::chrono::steady_clock::time_point newNow = + std::chrono::steady_clock::now(); for (int i = static_cast<int>(size) - 1; i >= 0; --i) { Socket::HandleResult res = Socket::HandleResult::SOCKET_CLOSED; @@ -438,7 +438,8 @@ public: private: /// Initialize the poll fds array with the right events - void setupPollFds(Poco::Timestamp &timeout) + void setupPollFds(std::chrono::steady_clock::time_point now, + int &timeoutMaxMs) { const size_t size = _pollSockets.size(); @@ -448,7 +449,7 @@ private: { _pollFds[i].fd = _pollSockets[i]->getFD(); _pollFds[i].events = _pollSockets[i]->getPollEvents(); - _pollSockets[i]->updateTimeout(timeout); + _pollSockets[i]->updateTimeout(now, timeoutMaxMs); _pollFds[i].revents = 0; } @@ -669,7 +670,7 @@ protected: /// Called when a polling event is received. /// @events is the mask of events that triggered the wake. - HandleResult handlePoll(const Poco::Timestamp & /* now */, + HandleResult handlePoll(std::chrono::steady_clock::time_point /* now */, const int events) override { assert(isCorrectThread()); commit e9dbab6900c758b820d2cff54436b608c95e2df6 Author: Michael Meeks <[email protected]> Date: Fri Mar 17 18:56:59 2017 +0000 Always call handlePoll so we can handle timeouts. diff --git a/net/Socket.cpp b/net/Socket.cpp index 7af87601..a0f67d0e 100644 --- a/net/Socket.cpp +++ b/net/Socket.cpp @@ -67,16 +67,20 @@ SocketPoll::~SocketPoll() _thread.join(); } - ::close(_wakeup[0]); - ::close(_wakeup[1]); + { + std::lock_guard<std::mutex> lock(getPollWakeupsMutex()); + auto it = std::find(getWakeupsArray().begin(), + getWakeupsArray().end(), + _wakeup[1]); - std::lock_guard<std::mutex> lock(getPollWakeupsMutex()); - auto it = std::find(getWakeupsArray().begin(), - getWakeupsArray().end(), - _wakeup[1]); + if (it != getWakeupsArray().end()) + getWakeupsArray().erase(it); + } - if (it != getWakeupsArray().end()) - getWakeupsArray().erase(it); + ::close(_wakeup[0]); + ::close(_wakeup[1]); + _wakeup[0] = -1; + _wakeup[1] = -1; } void SocketPoll::startThread() diff --git a/net/Socket.hpp b/net/Socket.hpp index 222f7b6a..79ad57e4 100644 --- a/net/Socket.hpp +++ b/net/Socket.hpp @@ -316,25 +316,22 @@ public: Poco::Timestamp newNow; for (int i = static_cast<int>(size) - 1; i >= 0; --i) { - if (_pollFds[i].revents) + Socket::HandleResult res = Socket::HandleResult::SOCKET_CLOSED; + try { - Socket::HandleResult res = Socket::HandleResult::SOCKET_CLOSED; - try - { - res = _pollSockets[i]->handlePoll(newNow, _pollFds[i].revents); - } - catch (const std::exception& exc) - { - LOG_ERR("Error while handling poll for socket #" << - _pollFds[i].fd << " in " << _name << ": " << exc.what()); - } + res = _pollSockets[i]->handlePoll(newNow, _pollFds[i].revents); + } + catch (const std::exception& exc) + { + LOG_ERR("Error while handling poll for socket #" << + _pollFds[i].fd << " in " << _name << ": " << exc.what()); + } - if (res == Socket::HandleResult::SOCKET_CLOSED) - { - LOG_DBG("Removing socket #" << _pollFds[i].fd << " (of " << - _pollSockets.size() << ") from " << _name); - _pollSockets.erase(_pollSockets.begin() + i); - } + if (res == Socket::HandleResult::SOCKET_CLOSED) + { + LOG_DBG("Removing socket #" << _pollFds[i].fd << " (of " << + _pollSockets.size() << ") from " << _name); + _pollSockets.erase(_pollSockets.begin() + i); } } @@ -378,7 +375,8 @@ public: rc = ::write(fd, "w", 1); } while (rc == -1 && errno == EINTR); - assert (rc != -1 || errno == EAGAIN || errno == EWOULDBLOCK); + if (rc != -1 || errno == EAGAIN || errno == EWOULDBLOCK) + LOG_WRN("wakeup socket #" << fd << " is closd at wakeup? error: " << errno); } /// Wakeup the main polling loop in another thread @@ -676,6 +674,9 @@ protected: { assert(isCorrectThread()); + if (!events) + return Socket::HandleResult::CONTINUE; + // FIXME: need to close input, but not output (?) bool closed = (events & (POLLHUP | POLLERR | POLLNVAL)); _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
