[Libreoffice-commits] online.git: Branch 'private/Ashod/nonblocking' - net/ServerSocket.hpp net/Socket.hpp

Michael Meeks michael.meeks at collabora.com
Fri Feb 24 22:56:59 UTC 2017


 net/ServerSocket.hpp |    2 +-
 net/Socket.hpp       |   28 ++++++++++++++++++++--------
 2 files changed, 21 insertions(+), 9 deletions(-)

New commits:
commit ba0cc1fc6b75e08b91734c90425dd695e6ebf398
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Fri Feb 24 22:56:20 2017 +0000

    Add initial support for socket timeouts.

diff --git a/net/ServerSocket.hpp b/net/ServerSocket.hpp
index a206e7c..1d0f2a5 100644
--- a/net/ServerSocket.hpp
+++ b/net/ServerSocket.hpp
@@ -73,7 +73,7 @@ public:
         return POLLIN;
     }
 
-    HandleResult handlePoll(int events) override
+    HandleResult handlePoll(const Poco::Timestamp &/* now */, int events) override
     {
         if (events & POLLIN)
         {
diff --git a/net/Socket.hpp b/net/Socket.hpp
index 59be92b..d78e3c9 100644
--- a/net/Socket.hpp
+++ b/net/Socket.hpp
@@ -25,6 +25,8 @@
 #include <mutex>
 #include <sstream>
 
+#include <Poco/Timespan.h>
+#include <Poco/Timestamp.h>
 #include <Poco/Net/SocketAddress.h>
 
 #include "Log.hpp"
@@ -47,15 +49,18 @@ public:
         close(_fd);
     }
 
-    // Returns the OS native socket fd.
+    /// Returns the OS native socket fd.
     int getFD() const { return _fd; }
 
     /// Return a mask of events we should be polling for
     virtual int getPollEvents() = 0;
 
+    /// Contract the poll timeout to match our needs
+    virtual void updateTimeout(Poco::Timestamp &/*timeout*/) { /* do nothing */ }
+
     /// Handle results of events returned from poll
     enum class HandleResult { CONTINUE, SOCKET_CLOSED };
-    virtual HandleResult handlePoll( int events ) = 0;
+    virtual HandleResult handlePoll(const Poco::Timestamp &now, int events) = 0;
 
     /// manage latency issues around packet aggregation
     void setNoDelay(bool noDelay = true)
@@ -175,26 +180,31 @@ public:
     }
 
     /// Poll the sockets for available data to read or buffer to write.
-    void poll(const int timeoutMs)
+    void poll(const int timeoutMaxMs)
     {
         const size_t size = _pollSockets.size();
 
+        Poco::Timestamp now;
+        Poco::Timestamp timeout = now;
+        timeout += Poco::Timespan(0 /* s */, timeoutMaxMs * 1000 /* us */);
+
         // The events to poll on change each spin of the loop.
-        setupPollFds();
+        setupPollFds(timeout);
 
         int rc;
         do
         {
-            rc = ::poll(&_pollFds[0], size + 1, timeoutMs);
+            rc = ::poll(&_pollFds[0], size + 1, (timeout - now)/1000);
         }
         while (rc < 0 && errno == EINTR);
 
         // Fire the callback and remove dead fds.
+        Poco::Timestamp newNow;
         for (int i = static_cast<int>(size) - 1; i >= 0; --i)
         {
             if (_pollFds[i].revents)
             {
-                if (_pollSockets[i]->handlePoll(_pollFds[i].revents) ==
+                if (_pollSockets[i]->handlePoll(newNow, _pollFds[i].revents) ==
                     Socket::HandleResult::SOCKET_CLOSED)
                 {
                     std::cout << "Removing client #" << _pollFds[i].fd << std::endl;
@@ -258,7 +268,7 @@ private:
     }
 
     /// Initialize the poll fds array with the right events
-    void setupPollFds()
+    void setupPollFds(Poco::Timestamp &timeout)
     {
         const size_t size = _pollSockets.size();
 
@@ -268,6 +278,7 @@ private:
         {
             _pollFds[i].fd = _pollSockets[i]->getFD();
             _pollFds[i].events = _pollSockets[i]->getPollEvents();
+            _pollSockets[i]->updateTimeout(timeout);
             _pollFds[i].revents = 0;
         }
 
@@ -315,7 +326,8 @@ public:
 
     /// Called when a polling event is received.
     /// @events is the mask of events that triggered the wake.
-    HandleResult handlePoll(const int events) override
+    HandleResult handlePoll(const Poco::Timestamp & /* now */,
+                            const int events) override
     {
         // FIXME: need to close input, but not output (?)
         bool closeSocket = false;


More information about the Libreoffice-commits mailing list