Switch socket management API to epoll() (#7785)
authorGabriel Braga <gabriel.braga@intra2net.com>
Tue, 9 Apr 2024 14:48:19 +0000 (16:48 +0200)
committerGabriel Braga <gabriel.braga@intra2net.com>
Tue, 9 Apr 2024 15:17:44 +0000 (17:17 +0200)
Previously all the server and client sockets were being managed by
the select() API, which operates using a fixed amount of client
sockets. This commit changes the code to adapt to the epoll() API.
This commit also could have a performance improvement due to epoll's
architecture.

Note: next commits should fix:
- The clock from sec to millisecs as the epoll_wait()
uses millisecs.
- Unit tests need to be changed to work properly.

20 files changed:
src/client_wrapper.hxx
src/command_client.cpp
src/command_client.hxx
src/command_server.cpp
src/command_server.hxx
src/connection.hxx
src/server.cpp
src/server.hxx
src/socket_client.cpp
src/socket_client.hxx
src/socket_handler.cpp
src/socket_handler.hxx
src/socket_server.cpp
src/socket_server.hxx
src/socket_wrapper.cpp
src/socket_wrapper.hxx
test/hello.cpp
test/reentrant.cpp
test/timeout.cpp
test/wrapper.cpp

index 73fda24..9c62d2d 100644 (file)
@@ -48,8 +48,8 @@ namespace libt2n
 class ConnectionWrapper
 {
     private:
-        long long command_timeout_usec;
-        long long hello_timeout_usec;
+        int command_timeout_millisec;
+        int hello_timeout_millisec;
 
     protected:
         log_level_values log_level;
@@ -58,8 +58,8 @@ class ConnectionWrapper
 
     public:
         ConnectionWrapper()
-            : command_timeout_usec(command_client::command_timeout_usec_default),
-              hello_timeout_usec(command_client::hello_timeout_usec_default),
+            : command_timeout_millisec(command_client::command_timeout_millisec_default),
+              hello_timeout_millisec(command_client::hello_timeout_millisec_default),
               log_level(none),
               logstream(NULL)
             { }
@@ -93,17 +93,17 @@ class ConnectionWrapper
             return true;
         }
 
-        long long get_command_timeout_usec(void)
-            { return command_timeout_usec; }
+        int get_command_timeout_millisec() const
+            { return command_timeout_millisec; }
 
-        void set_command_timeout_usec(long long _command_timeout_usec)
-            { command_timeout_usec=_command_timeout_usec; }
+        void set_command_timeout_millisec(int _command_timeout_millisec)
+            { command_timeout_millisec=_command_timeout_millisec; }
 
-        long long get_hello_timeout_usec(void)
-            { return hello_timeout_usec; }
+        int get_hello_timeout_millisec() const
+            { return hello_timeout_millisec; }
 
-        void set_hello_timeout_usec(long long _hello_timeout_usec)
-            { hello_timeout_usec=_hello_timeout_usec; }
+        void set_hello_timeout_millisec(int _hello_timeout_millisec)
+            { hello_timeout_millisec=_hello_timeout_millisec; }
 
         virtual void set_logging(std::ostream *_logstream, log_level_values _log_level);
 
@@ -225,8 +225,8 @@ class T2nSingletonWrapper : public T2nSingletonWrapperMessages
                 throw std::logic_error(NotInitializedMessage);
 
             std::auto_ptr<Client> stub(new Client(WrappedConnection->get_connection(),
-                WrappedConnection->get_command_timeout_usec(),
-                WrappedConnection->get_hello_timeout_usec()));
+                                                  WrappedConnection->get_command_timeout_millisec(),
+                                                  WrappedConnection->get_hello_timeout_millisec()));
 
             SingletonObject=std::auto_ptr<T2nSingletonWrapper>(new T2nSingletonWrapper(stub));
         }
@@ -267,11 +267,11 @@ class T2nSingletonWrapper : public T2nSingletonWrapperMessages
         }
 
         /// return a pointer to the ConnectionWrapper currently in use
-        static ConnectionWrapper* get_connection_wrapper(void)
+        static ConnectionWrapper* get_connection_wrapper()
             { return WrappedConnection.get(); }
 
         /// manually establish the connection without actually executing a call
-        static void ensure_singleton_there(void)
+        static void ensure_singleton_there()
         {
             if (SingletonObject.get() == NULL)
                 init();
index 924fdbf..0780f73 100644 (file)
@@ -32,6 +32,7 @@ on this file might be covered by the GNU General Public License.
 #include <boost/bind.hpp>
 
 #include "command_client.hxx"
+#include "monotonic_clock.hxx"
 
 #include <config.h>
 
@@ -43,15 +44,15 @@ namespace libt2n
 /**
  * Constructor
  * @param _c connection for this command. Ownership of the pointer is outside.
- * @param _command_timeout_usec timeout until the command has to be completed
- * @param _hello_timeout_usec timeout until hello has to be received
+ * @param _command_timeout_millisec timeout until the command has to be completed
+ * @param _hello_timeout_millisec timeout until hello has to be received
  */
-command_client::command_client(client_connection* _c, long long _command_timeout_usec, long long _hello_timeout_usec)
+command_client::command_client(client_connection* _c, int _command_timeout_millisec, int _hello_timeout_millisec)
     : c(_c)
     , constructorException(NULL)
 {
-    command_timeout_usec=_command_timeout_usec;
-    hello_timeout_usec=_hello_timeout_usec;
+    command_timeout_millisec=_command_timeout_millisec;
+    hello_timeout_millisec=_hello_timeout_millisec;
 
     // for reconnects
     c->add_callback(new_connection,bind(&command_client::read_hello, boost::ref(*this)));
@@ -114,18 +115,24 @@ void command_client::replace_connection(client_connection* _c)
 }
 
 /** @brief return a complete packet
-    @param usec_timeout maximum microseconds to wait until the packet is complete
+    @param millisec_timeout maximum microseconds to wait until the packet is complete
     @retval packet data as std::string
 
     @note throws a t2n_transfer_error if the timeout is exceeded
 */
-std::string command_client::read_packet(const long long &usec_timeout)
+std::string command_client::read_packet(const int &millisec_timeout)
 {
     string resultpacket;
     bool got_packet=false;
-    long long my_timeout=usec_timeout;
+    int my_timeout=millisec_timeout, timeout_checkpoint;
+
     while(!(got_packet=c->get_packet(resultpacket)) && my_timeout > 0  && !c->is_closed())
-        c->fill_buffer(my_timeout,&my_timeout);
+    {
+        timeout_checkpoint=monotonic_clock_gettime_sec();
+        c->fill_buffer(millisec_timeout);
+        my_timeout -= abs(monotonic_clock_gettime_sec() - timeout_checkpoint);
+    }
+
 
     if (!got_packet)
         throw t2n_transfer_error("timeout exceeded");
@@ -141,10 +148,12 @@ void command_client::read_hello()
 {
     string resultpacket;
     bool got_packet=false;
-    long long my_timeout=hello_timeout_usec;
+    int my_timeout=hello_timeout_millisec, timeout_checkpoint;
     while(!(got_packet=c->get_packet(resultpacket)) && my_timeout > 0  && !c->is_closed())
     {
-        c->fill_buffer(my_timeout,&my_timeout);
+        timeout_checkpoint=monotonic_clock_gettime_sec();
+        c->fill_buffer(my_timeout);
+        my_timeout -= abs(monotonic_clock_gettime_sec() - timeout_checkpoint);
 
         c->peek_packet(resultpacket);
         check_hello(resultpacket);           // will throw before timeout if wrong data received
@@ -276,7 +285,7 @@ void command_client::send_command(command* cmd, result_container &res)
 
     c->write(ofs.str());
 
-    istringstream ifs(read_packet(command_timeout_usec));
+    istringstream ifs(read_packet(command_timeout_millisec));
     boost::archive::binary_iarchive ia(ifs);
 
     try
index fc72ca7..cef834b 100644 (file)
@@ -35,42 +35,48 @@ namespace libt2n
 class command_client
 {
     public:
-        static const long long command_timeout_usec_default=90000000;
-        static const long long hello_timeout_usec_default=30000000;
+        static const int command_timeout_millisec_default=90000;
+        static const int hello_timeout_millisec_default=30000;
 
     private:
         client_connection *c;
 
-        long long hello_timeout_usec;
-        long long command_timeout_usec;
+        int hello_timeout_millisec;
+        int command_timeout_millisec;
+
+        t2n_exception *constructorException;
 
         void read_hello();
-        std::string read_packet(const long long &usec_timeout);
+        std::string read_packet(const int &millisec_timeout);
         bool check_hello(const std::string& hellostr);
 
-        t2n_exception *constructorException;
-
     public:
-        command_client(client_connection* _c,
-            long long _command_timeout_usec=command_timeout_usec_default,
-            long long _hello_timeout_usec=hello_timeout_usec_default);
+        explicit command_client(client_connection* _c,
+            int _command_timeout_millisec=command_timeout_millisec_default,
+            int _hello_timeout_millisec=hello_timeout_millisec_default);
+
         virtual ~command_client();
 
         void replace_connection(client_connection* _c);
 
         void send_command(command* cmd, result_container &res);
 
-        void set_command_timeout_usec(long long _command_timeout_usec=command_timeout_usec_default)
-            { command_timeout_usec=_command_timeout_usec; }
-        void set_hello_timeout_usec(long long _hello_timeout_usec=hello_timeout_usec_default)
-            { hello_timeout_usec=_hello_timeout_usec; }
-        long long get_command_timeout_usec(void)
-            { return command_timeout_usec; }
-        long long get_hello_timeout_usec(void)
-            { return hello_timeout_usec; }
-        bool is_connection_closed(void)
+        void set_command_timeout_millisec(int _command_timeout_millisec=command_timeout_millisec_default)
+            { command_timeout_millisec=_command_timeout_millisec; }
+
+        void set_hello_timeout_millisec(int _hello_timeout_millisec=hello_timeout_millisec_default)
+            { hello_timeout_millisec=_hello_timeout_millisec; }
+
+        int get_command_timeout_millisec() const
+            { return command_timeout_millisec; }
+
+        int get_hello_timeout_millisec() const
+            { return hello_timeout_millisec; }
+
+        bool is_connection_closed()
             { return c->is_closed(); }
-        t2n_exception* get_constuctor_exception(void)
+
+        t2n_exception* get_constructor_exception()
             { return constructorException; }
 };
 
index 21aeb79..de18c56 100644 (file)
@@ -161,17 +161,16 @@ void command_server::handle_packet(const std::string& packet, server_connection*
 }
 
 /** @brief handle incoming commands
-    @param[in,out] usec_timeout wait until new data is found, max timeout usecs.
+    @param[in,out] millisec_timeout wait until new data is found, max timeout millisecs.
             -1: wait endless, 0: instant return
-    @param[out] usec_timeout_remaining microseconds from the timeout that were not used
 */
-void command_server::handle(long long usec_timeout, long long* usec_timeout_remaining)
+void command_server::handle(int millisec_timeout)
 {
     guard_handle++;
 
     try
     {
-        if (s.fill_buffer(usec_timeout,usec_timeout_remaining))
+        if (s.fill_buffer(millisec_timeout))
         {
             std::string packet;
             unsigned int conn_id = 0;
index 95dfe32..384677c 100644 (file)
@@ -46,7 +46,7 @@ class command_server
         command_server(server& _s);
         ~command_server();
 
-        void handle(long long usec_timeout=-1, long long* usec_timeout_remaining=NULL);
+        void handle(int millisec_timeout=-1);
 
         void send_hello(unsigned int conn_id);
 
index f737559..b178fe1 100644 (file)
@@ -63,29 +63,27 @@ class connection
 
         void do_callbacks(callback_event_type event);
 
-        void reopen(void);
+        void reopen();
         void remove_incomplete_packets();
 
     public:
         virtual ~connection();
 
         /// is this connection closed or not
-        bool is_closed()
+        bool is_closed() const
             { return closed; }
 
         /// close this connection
         virtual void close();
 
         /** @brief look for new data and store it in the local buffer
-            @param usec_timeout wait until new data is found, max timeout usecs.
+            @param millisec_timeout wait until new data is found, max timeout secs.
                   -1: wait endless
                    0: return instantly
-            @param usec_timeout_remaining if non-NULL the function will write the
-                  not used time to the given target
             @retval true if new data was found (does not mean that the received data 
                     is a complete packet though)
         */
-        virtual bool fill_buffer(long long usec_timeout=-1,long long* usec_timeout_remaining=NULL)=0;
+        virtual bool fill_buffer(int millisec_timeout)=0;
 
         bool get_packet(std::string& data);
 
index 7ee28f2..c61dbf4 100644 (file)
@@ -95,7 +95,7 @@ void server_connection::add_callback(callback_event_type event, const boost::fun
 server::server()
     : callbacks(__events_end)
 {
-    set_default_timeout(30);
+    set_default_timeout(30000);
     set_logging(NULL,none);
     next_id=1;
 }
@@ -168,7 +168,6 @@ unsigned int server::add_connection(server_connection* newconn)
         for (i=callbacks[e].begin(); i != ie; i++)
             newconn->add_callback(static_cast<callback_event_type>(e),bind(*i,cid));
     }
-
     LOGSTREAM(debug,"new connection accepted, id: " << cid);
 
     do_callbacks(new_connection,cid);
@@ -185,9 +184,7 @@ void server::set_logging(std::ostream *_logstream, log_level_values _log_level)
 
 /**
     @brief Gets a connection by id
-    
     @param conn_id Connection ID
-    
     @retval Pointer to connection object
 */
 server_connection* server::get_connection(unsigned int conn_id)
index ad82287..cd0ae91 100644 (file)
@@ -52,6 +52,7 @@ class server_connection : public connection
     private:
         int timeout;
         int last_action_time;
+
         unsigned int connection_id;
 
         void set_server(server* _my_server)
@@ -63,7 +64,7 @@ class server_connection : public connection
     protected:
         server *my_server;
 
-        server_connection(int _timeout);
+        explicit server_connection(int _timeout);
         virtual ~server_connection();
 
         std::ostream* get_logstream(log_level_values level);
@@ -75,7 +76,7 @@ class server_connection : public connection
             { timeout=_timeout; }
 
         /// get the id of this connection within the server object
-        unsigned int get_id()
+        unsigned int get_id() const
             { return connection_id; }
 
         void add_callback(callback_event_type event, const boost::function<void ()>& func);
@@ -103,7 +104,7 @@ class server
 
         server();
 
-        virtual bool fill_connection_buffers(void)=0;
+        virtual bool fill_connection_buffers()=0;
 
         unsigned int add_connection(server_connection* newconn);
 
@@ -117,7 +118,7 @@ class server
             { default_timeout=_default_timeout; }
 
         /// get the current default timeout for client connections
-        int get_default_timeout(void)
+        int get_default_timeout() const
             { return default_timeout; }
 
         void set_logging(std::ostream *_logstream, log_level_values _log_level);
@@ -127,15 +128,13 @@ class server
         void add_callback(callback_event_type event, const boost::function<void (unsigned int)>& func);
 
         /** @brief look for new data and store it in the local buffer
-            @param usec_timeout wait until new data is found, max timeout usecs.
+            @param millisec_timeout wait until new data is found, max timeout millisecs.
                   -1: wait endless
                    0: return instantly
-            @param usec_timeout_remaining if non-NULL the function will write the
-                  not used time to the given target
             @retval true if new data was found (does not mean that the received data 
                     is a complete packet though)
         */
-        virtual bool fill_buffer(long long usec_timeout=-1, long long* usec_timeout_remaining=NULL)=0;
+        virtual bool fill_buffer(int millisec_timeout=-1)=0;
 
         void close();
 
index 954bb30..5aa32a4 100644 (file)
@@ -20,25 +20,19 @@ This exception does not invalidate any other reasons why a work based
 on this file might be covered by the GNU General Public License.
 */
 
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
+#include <cerrno>
 #include <sys/socket.h>
 #include <sys/un.h>
-#include <sys/time.h>
+#include <sys/epoll.h>
 #include <arpa/inet.h>
 #include <netinet/in.h>
 #include <netdb.h>
 #include <fcntl.h>
-#include <time.h>
-
-#include <pwd.h>
-#include <grp.h>
+#include <ctime>
 
 #include <sstream>
 
+#include "monotonic_clock.hxx"
 #include "socket_client.hxx"
 #include "t2n_exception.hxx"
 #include "log.hxx"
@@ -49,13 +43,13 @@ namespace libt2n
 {
 
 /// returns a closed connection if connection could not be established, call get_last_error_msg() for details
-socket_client_connection::socket_client_connection(int _port, const std::string& _server, 
-            long long _connect_timeout_usec, int _max_retries,
-            std::ostream *_logstream, log_level_values _log_level)
+socket_client_connection::socket_client_connection(int _port, const std::string& _server,
+                                                   int _connect_timeout_millisec, int _max_retries,
+                                                   std::ostream *_logstream, log_level_values _log_level)
     : client_connection(), socket_handler(0,tcp_s)
 {
     max_retries=_max_retries;
-    connect_timeout_usec=_connect_timeout_usec;
+    connect_timeout_millisec=_connect_timeout_millisec;
 
     server=_server;
     port=_port;
@@ -79,13 +73,12 @@ socket_client_connection::socket_client_connection(int _port, const std::string&
 }
 
 /// returns a closed connection if connection could not be established, call get_last_error_msg() for details
-socket_client_connection::socket_client_connection(const std::string& _path,
-            long long _connect_timeout_usec, int _max_retries,
-            std::ostream *_logstream, log_level_values _log_level)
+socket_client_connection::socket_client_connection(const std::string& _path, int _connect_timeout_millisec, int _max_retries,
+                                                   std::ostream *_logstream, log_level_values _log_level)
     : client_connection(), socket_handler(0,unix_s)
 {
     max_retries=_max_retries;
-    connect_timeout_usec=_connect_timeout_usec;
+    connect_timeout_millisec=_connect_timeout_millisec;
 
     path=_path;
 
@@ -139,6 +132,8 @@ void socket_client_connection::tcp_connect(int max_retries)
     if (!sock)
         throw t2n_connect_error(string("socket() error: ")+strerror(errno));
 
+    socket_handler::create_epoll();
+
     try
     {
         connect_with_timeout((struct sockaddr *) &sock_addr,sizeof(sock_addr));
@@ -178,6 +173,8 @@ void socket_client_connection::unix_connect(int max_retries)
     if (!sock)
         throw t2n_connect_error(string("socket() error: ")+strerror(errno));
 
+    socket_handler::create_epoll();
+
     try
     {
         connect_with_timeout((struct sockaddr *) &unix_addr, sizeof(unix_addr));
@@ -193,6 +190,7 @@ void socket_client_connection::unix_connect(int max_retries)
         else
             throw t2n_connect_error("no more retries left after connect error");
     }
+
 }
 
 /// execute a connect on a prepared socket (tcp or unix) respecting timeouts
@@ -220,30 +218,11 @@ void socket_client_connection::connect_with_timeout(struct sockaddr *sock_addr,u
         {
             LOGSTREAM(debug,"connect_with_timeout(): EINPROGRESS");
 
-            /* set timeout */
-            struct timeval tval;
-            struct timeval *timeout_ptr;
-
-            if (connect_timeout_usec == -1)
-                timeout_ptr = NULL;
-            else
-            {
-                timeout_ptr = &tval;
+            int nfds;
+            while ((nfds=epoll_wait(epoll_fd,epoll_events,EPOLL_MAX_EVENTS,timeout)) &&
+                    nfds < 0 && errno==EINTR);
 
-                // convert timeout from long long usec to int sec + int usec
-                tval.tv_sec = connect_timeout_usec / 1000000;
-                tval.tv_usec = connect_timeout_usec % 1000000;
-            }
-
-            fd_set connect_socket_set;
-            FD_ZERO(&connect_socket_set);
-            FD_SET(sock,&connect_socket_set);
-
-            int ret;
-            while ((ret=select(FD_SETSIZE, NULL, &connect_socket_set, NULL, timeout_ptr)) &&
-                    ret < 0 && errno==EINTR);
-
-            if (ret < 0)
+            if (nfds < 0)
                 throw t2n_connect_error(string("connect() error (select): ")+strerror(errno));
 
             socklen_t sopt=sizeof(int);
@@ -268,9 +247,9 @@ void socket_client_connection::close()
     }
 }
 
-/** @brief try to reconnect the current connection with the same connection credentials (host and port or path)
-
-    @note will throw an exeption if reconnecting not possible
+/**
+ * @brief try to reconnect the current connection with the same connection credentials (host and port or path)
+ * @note will throw an exception if reconnecting not possible
 */
 void socket_client_connection::reconnect()
 {
@@ -286,7 +265,7 @@ void socket_client_connection::reconnect()
     else if (type == unix_s)
         unix_connect(max_retries);
 
-    // connection is open now, otherwise an execption would have been thrown
+    // connection is open now, otherwise an exception would have been thrown
     reopen();
 
     LOGSTREAM(debug,"reconnect() done, client_connection::is_closed() now " << client_connection::is_closed());
index 037c6ca..7f5d297 100644 (file)
@@ -30,14 +30,13 @@ struct sockaddr;
 namespace libt2n
 {
 /** @brief a connection from client to server using sockets.
-
     Use this class to connect from a client to a server.
  */
 class socket_client_connection : public client_connection, public socket_handler
 {
     public:
-        static const int max_retries_default=3;
-        static const long long connect_timeout_usec_default=30000000;
+        static const int max_retries_default=5;
+        static const int connect_timeout_millisec_default=30000;
 
     private:
         void real_write(const std::string& data)
@@ -48,7 +47,7 @@ class socket_client_connection : public client_connection, public socket_handler
         void connect_with_timeout(struct sockaddr *sock_addr,unsigned int sockaddr_size);
 
         int max_retries;
-        long long connect_timeout_usec;
+        int connect_timeout_millisec;
 
         std::string path;
         std::string server;
@@ -62,34 +61,30 @@ class socket_client_connection : public client_connection, public socket_handler
             { return client_connection::get_logstream(level); }
 
     public:
-        socket_client_connection(int _port, const std::string& _server="127.0.0.1", 
-            long long _connect_timeout_usec=connect_timeout_usec_default, 
-            int _max_retries=max_retries_default,
-            std::ostream *_logstream=NULL, log_level_values _log_level=none);
-        socket_client_connection(const std::string& _path,
-            long long _connect_timeout_usec=connect_timeout_usec_default, 
+        explicit socket_client_connection(int _port, const std::string& _server="127.0.0.1",
+                                 int _connect_timeout_millisec=connect_timeout_millisec_default,
+                                 int _max_retries=max_retries_default, std::ostream *_logstream=NULL,
+                                 log_level_values _log_level=none);
+
+        explicit socket_client_connection(const std::string& _path,
+            int _connect_timeout_millisec=connect_timeout_millisec_default,
             int _max_retries=max_retries_default,
             std::ostream *_logstream=NULL, log_level_values _log_level=none);
 
         ~socket_client_connection();
 
         /** @brief read data from the socket and copy it into buffer
-            @param usec_timeout wait until new data is found, max timeout usecs.
-                  -1: wait endless
-                   0: return instantly
-            @param usec_timeout_remaining if non-NULL the function will write the
-                  not used time to the given target
             @retval true if new data was found (does not mean that the received data 
                     is a complete packet though)
         */
-        bool fill_buffer(long long usec_timeout=-1, long long *usec_timeout_remaining=NULL)
-            { return socket_handler::fill_buffer(buffer,usec_timeout,usec_timeout_remaining); }
+        bool fill_buffer(int millisec_timeout)
+            { return socket_handler::fill_buffer(buffer, millisec_timeout); }
 
         virtual void close();
 
         void reconnect();
 
-        std::string get_last_error_msg(void)
+        std::string get_last_error_msg()
             { return lastErrorMsg; }
 };
 
index f1f5ef7..355f623 100644 (file)
@@ -28,6 +28,7 @@ on this file might be covered by the GNU General Public License.
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <sys/time.h>
+#include <sys/epoll.h>
 #include <arpa/inet.h>
 #include <netinet/in.h>
 #include <netdb.h>
@@ -50,11 +51,11 @@ namespace libt2n
 {
 
 socket_handler::socket_handler(int _sock, socket_type_value _socket_type)
-: sock(_sock)
-, recv_buffer_size( default_recv_buffer_size )
-, write_block_size( default_write_block_size )
-, write_timeout( default_write_timeout )
-, socket_type(_socket_type)
+    : sock(_sock)
+    , recv_buffer_size( default_recv_buffer_size )
+    , write_block_size( default_write_block_size )
+    , write_timeout( default_write_timeout )
+    , socket_type(_socket_type)
 {
 }
 
@@ -66,6 +67,7 @@ socket_handler::~socket_handler()
     if (sock != -1)
     {
         shutdown(sock,SHUT_RDWR);
+        remove_from_epoll(sock);
         ::close(sock);
 
         sock = -1;
@@ -76,12 +78,18 @@ socket_handler::~socket_handler()
 /// by the connection class you are using.
 void socket_handler::close()
 {
-    LOGSTREAM(debug,"close connection");
-    // graceful shutdown
-    shutdown(sock,SHUT_RDWR);
-    ::close(sock);
+    if (sock != -1)
+    {
+        LOGSTREAM(debug, "close connection");
+        // graceful shutdown
+        shutdown(sock, SHUT_RDWR);\
+        //taking it out of the epoll pool
 
-    sock = -1;
+        remove_from_epoll(sock);
+        ::close(sock);
+
+        sock = -1;
+    }
 }
 
 /// set options like fast reuse and keepalive every socket should have
@@ -143,12 +151,12 @@ void socket_handler::set_recv_buffer_size(unsigned int new_recv_buffer_size)
 
 
 /**
- * @brief set new size for the data chunks when writeing.
+ * @brief set new size for the data chunks when writing.
  * @param new_write_block_size the new chunk size.
  *
  * The write block size determines the amount of data which is tried to write
- * to the socket when data needs to be sended.
- * Since writing data is done in a loop, this does not limit the amunt of data which can
+ * to the socket when data needs to be sent.
+ * Since writing data is done in a loop, this does not limit the amount of data which can
  * be written.
  *
  * The value is normalized to be at least 512 bytes and at max 32K bytes.
@@ -174,39 +182,13 @@ void socket_handler::set_write_timeout(long long new_write_timeout)
 
 
 /** @brief check if new data is waiting on the raw socket
-    @param[in,out] usec_timeout wait until new data is found, max timeout usecs.
+    @param[in,out] timeout wait until new data is found, max timeout millisecs.
             -1: wait endless
             0: return instantly
-    @param[out] usec_timeout_remaining microseconds from the timeout that were not used
 */
-bool socket_handler::data_waiting(long long usec_timeout,long long* usec_timeout_remaining)
+bool socket_handler::data_waiting(int timeout)
 {
-    // just our socket
-    fd_set active_fd_set;
-    FD_ZERO (&active_fd_set);
-    FD_SET (sock, &active_fd_set);
-
-    /* set timeout */
-    struct timeval tval;
-    struct timeval *timeout_ptr;
-
-    if (usec_timeout == -1)
-        timeout_ptr = NULL;
-    else
-    {
-        timeout_ptr = &tval;
-
-        // convert timeout from long long usec to int sec + int usec
-        tval.tv_sec = usec_timeout / 1000000;
-        tval.tv_usec = usec_timeout % 1000000;
-    }
-
-    int ret=select (FD_SETSIZE, &active_fd_set, NULL, NULL, timeout_ptr);
-
-    // return the timeout we did not use
-    // todo: this is linux specific according to man 2 select
-    if (usec_timeout > 0 && usec_timeout_remaining != NULL)
-        *usec_timeout_remaining=(tval.tv_sec*1000000)+tval.tv_usec;
+    int ret = epoll_wait(epoll_fd,epoll_events,EPOLL_MAX_EVENTS,timeout);
 
     if (ret > 0)
         return true;
@@ -216,15 +198,14 @@ bool socket_handler::data_waiting(long long usec_timeout,long long* usec_timeout
 
 /** @brief read data from the raw socket and copy it into the provided buffer
     @param buffer the buffer where to append the new data
-    @param[in,out] usec_timeout wait until new data is found, max timeout usecs.
+    @param[in,out] timeout wait until new data is found, max timeout millisecs.
             -1: wait endless
             0: return instantly
-    @param[out] usec_timeout_remaining microseconds from the timeout that were not used
 */
-bool socket_handler::fill_buffer(std::string& buffer, long long usec_timeout, long long *usec_timeout_remaining)
+bool socket_handler::fill_buffer(std::string& buffer,int timeout)
 {
     // fast path for timeout==0
-    if (usec_timeout==0 || data_waiting(usec_timeout,usec_timeout_remaining))
+    if (timeout == 0 || data_waiting(timeout))
         return fill_buffer(buffer);
     else
         return false;
@@ -303,7 +284,7 @@ void socket_handler::socket_write(const std::string& data)
         while ((rtn=::write(sock, data.data()+offset, write_size)) == -1 &&
                (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR))
         {
-            wait_ready_to_write(sock,write_timeout);
+            wait_ready_to_write(write_timeout);
             LOGSTREAM(debug,"resuming write() call after EAGAIN or EINTR or EWOULDBLOCK");
         }
 
@@ -321,53 +302,78 @@ void socket_handler::socket_write(const std::string& data)
     }
 
     LOGSTREAM(debug,"wrote " << data.size() << " bytes");
-
-    return;
 } // eo socket_handler::socket_write(const std::string&)
 
 /// wait until the socket is ready to write again
-void socket_handler::wait_ready_to_write(int socket, long long write_block_timeout)
+void socket_handler::wait_ready_to_write(int write_block_timeout)
 {
-    // prepare socket sets
-    fd_set write_set[1];
-    fd_set except_set[1];
-    FD_ZERO(write_set);
-    FD_ZERO(except_set);
-    FD_SET(socket, write_set);
-    FD_SET(socket, except_set);
-
-    // prepare timeout struct
-    struct timeval tval;
-    struct timeval *timeout_ptr;
-
-    if (write_block_timeout == -1)
-        timeout_ptr = NULL;
-    else
-    {
-        timeout_ptr = &tval;
-
-        // convert timeout from long long usec to int sec + int usec
-        tval.tv_sec = write_block_timeout / 1000000;
-        tval.tv_usec = write_block_timeout % 1000000;
-    }
-
     // let's wait for the socket to become writable again...
     int rtn;
-    while ((rtn=::select(socket+1, NULL, write_set, except_set, timeout_ptr)) ==-1 && errno == EINTR);
+    while ((rtn=::epoll_wait(epoll_fd,epoll_events,EPOLL_MAX_EVENTS,write_block_timeout)) ==-1 && errno == EINTR);
 
-    if (rtn > 0 && (!FD_ISSET(socket,write_set)) && FD_ISSET(socket, except_set))
+    if (rtn > 0)
     {
-        // if we are selected but cannot write and have an exception
-        // we have serious trouble...
-        EXCEPTIONSTREAM(error,t2n_transfer_error,"exception on socket; cannot write any more.");
+        for (int i=0; i < rtn; ++i)
+        {
+            // Something very wrong happened
+            if(epoll_events[i].events != EPOLLOUT && epoll_events[i].events == EPOLLERR)
+                EXCEPTIONSTREAM(error,t2n_transfer_error,"exception on socket; cannot write any more.");
+        }
     }
+    else if (rtn == 0)
+        EXCEPTIONSTREAM(error,t2n_transfer_error,"timeout on epoll_wait() for write");
+    else if (rtn == -1)
+        EXCEPTIONSTREAM(error,t2n_transfer_error,"cannot find socket to write: " << strerror(errno));
+}
+
+/**
+ * @brief  initialize the epoll pool and add the primary socket to it
+ * assuming the socket is already created!
+ */
+void socket_handler::create_epoll()
+{
+    struct epoll_event ev = {};
+    ev.events = EPOLLIN;
+    epoll_fd = epoll_create1(EPOLL_CLOEXEC);
 
-    if (rtn==0)
-        EXCEPTIONSTREAM(error,t2n_transfer_error,"timeout on select() for write");
+    if (epoll_fd == -1)
+        EXCEPTIONSTREAM(error,t2n_server_error, "error opening epoll: " << strerror(errno));
 
-    if (rtn==-1)
-        EXCEPTIONSTREAM(error,t2n_transfer_error,"cannot select() for write: " << strerror(errno));
+    //adding sock (fd) to the set of events that epoll API will monitor
+    if(sock != -1)
+        add_to_epoll(sock,&sock);
+    else
+        EXCEPTIONSTREAM(error,t2n_server_error, "socket not previously created impossible to add to epoll");
 }
 
+/**
+ * @brief this adds one file descriptor to the epoll pool to monitor events
+ * assuming the epoll was previously created
+ * @param fd the file descriptor we want to monitor
+ */
+void socket_handler::add_to_epoll(int fd,void* ptr)
+{
+    struct epoll_event ev;
+    ev.events = EPOLLIN;
+    ev.data.ptr = ptr;
+    //adding newsock (client fd) to the set of events that epoll API will monitor
+    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd,&ev) == -1)
+        EXCEPTIONSTREAM(error,t2n_server_error,"error adding server socket to epoll(): " << strerror(errno));
+
+}
+
+/**
+ * @brief this removes one file descriptor from the epoll pool
+ * assuming the epoll was previously created and the fd was
+ * previously added somewhere
+ * @param fd the file descriptor we want to monitor
+ */
+void socket_handler::remove_from_epoll(int fd)
+{
+    struct epoll_event ev;
+    //removing (client fd) from the set of events that epoll API monitors
+    if (epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd,&ev) == -1)
+        LOGSTREAM(debug,"error deleting server socket to epoll(): " << strerror(errno) << "  ...ignoring"<<endl);
+}
 
 }
index b6776ec..bf4b254 100644 (file)
@@ -23,9 +23,12 @@ on this file might be covered by the GNU General Public License.
 #define __LIBT2N_SOCKET_HANDLER
 
 #include <iostream>
+#include <sys/epoll.h>
 
 #include "types.hxx"
 
+#define EPOLL_MAX_EVENTS 32
+
 namespace libt2n
 {
 
@@ -37,18 +40,21 @@ class socket_handler
     private:
         static const unsigned int default_recv_buffer_size=2048;
         static const unsigned int default_write_block_size=4096;
-        static const long long default_write_timeout=30000000;
-
+        static const int default_write_timeout=30000;
         socket_type_value socket_type;
 
-        bool data_waiting(long long usec_timeout,long long *usec_timeout_remaining=NULL);
-        void wait_ready_to_write(int socket, long long write_block_timeout);
+        bool data_waiting(int timeout);
+        void wait_ready_to_write(int write_block_timeout);
 
     protected:
+        int epoll_fd;
+        struct epoll_event epoll_events[EPOLL_MAX_EVENTS];
+
         int sock;
         unsigned int recv_buffer_size;
         unsigned int write_block_size;
-        long long write_timeout;
+        time_t write_timeout;
+        time_t timeout;
 
         socket_handler(int _sock, socket_type_value _socket_type);
         ~socket_handler();
@@ -62,15 +68,19 @@ class socket_handler
 
         virtual void close();
 
-        bool fill_buffer(std::string& buffer, long long usec_timeout, long long* usec_timeout_remaining=NULL);
+        bool fill_buffer(std::string& buffer, int timeout);
         bool fill_buffer(std::string& buffer);
 
+        void create_epoll();
+        void remove_from_epoll(int fd);
+        void add_to_epoll(int fd,void* ptr);
+
     public:
         /// is this a tcp or unix socket connection
         socket_type_value get_type()
             { return socket_type; }
 
-        int get_socket()
+        int get_socket() const
             { return sock; }
 
         bool is_closed();
index d6ca439..b8c4099 100644 (file)
@@ -33,12 +33,11 @@ on this file might be covered by the GNU General Public License.
 #include <netinet/in.h>
 #include <netdb.h>
 #include <fcntl.h>
-#include <time.h>
 #include <pwd.h>
 #include <grp.h>
-
 #include <sstream>
 
+#include "monotonic_clock.hxx"
 #include "socket_server.hxx"
 #include "t2n_exception.hxx"
 #include "log.hxx"
@@ -76,6 +75,8 @@ socket_server::socket_server(int port, const std::string& ip)
         EXCEPTIONSTREAM(error,t2n_server_error,"error binding socket: " << strerror(errno));
     }
 
+    create_epoll();
+
     start_listening();
 }
 
@@ -130,7 +131,10 @@ socket_server::socket_server(const std::string& path, mode_t filemode, const std
             EXCEPTIONSTREAM(error,t2n_server_error,"error changing socket ownership: " << strerror(errno));
     }
 
+    socket_handler::create_epoll();
+
     start_listening();
+
 }
 
 /**
@@ -142,7 +146,6 @@ socket_server::~socket_server()
     server::close();
 
     // server socket will be closed by destructor of socket_handler
-
     if (get_type()==unix_s)
         unlink(unix_path.c_str());
 
@@ -163,8 +166,6 @@ void socket_server::start_listening()
         EXCEPTIONSTREAM(error,t2n_server_error,"error listening to socket: " << strerror(errno));
 
     /* clear & insert server sock into the fd_tab to prepare select */
-    FD_ZERO(&connection_set);
-    FD_SET (sock, &connection_set);
     sockets_set.insert(sock);
 }
 
@@ -190,72 +191,51 @@ void socket_server::new_connection()
         EXCEPTIONSTREAM(error,t2n_server_error,"fatal error accepting connection: " << strerror(errno));
     }
 
-    FD_SET (newsock, &connection_set);
     sockets_set.insert(newsock);
 
+
     socket_server_connection *nc=new socket_server_connection(newsock, get_type(), get_default_timeout());
     nc->set_socket_options(newsock);
 
     add_connection(nc);
-
-    return;
+    add_to_epoll(newsock,nc);
 }
 
 /** @brief look for new connections and new data in any of the existing connections
-    @param usec_timeout wait until new data is found, max timeout usecs.
+    @param timeout wait until new data is found, max timeout millisecs.
             -1: wait endless
             0: return instantly
-    @param usec_timeout_remaining if non-NULL the function will write the
-            not used time to the given target
-    @retval true if new data was found (does not mean that the received data 
-            is a complete packet though)
 */
-bool socket_server::fill_buffer(long long usec_timeout,long long* usec_timeout_remaining)
+bool socket_server::fill_buffer(int timeout)
 {
-    fd_set used_fdset=connection_set;
-
-    /* set timeout */
-    struct timeval tval;
-    struct timeval *timeout_ptr;
-
-    if (usec_timeout == -1)
-        timeout_ptr = NULL;
-    else
-    {
-        timeout_ptr = &tval;
-
-        // timeout von long long usec in int sec + int usec umrechnen
-        tval.tv_sec = usec_timeout / 1000000;
-        tval.tv_usec = usec_timeout % 1000000;
-    }
-
-    int ret=select (FD_SETSIZE, &used_fdset, NULL, NULL, timeout_ptr);
-
-    // return the timeout we did not use
-    if (usec_timeout > 0 && usec_timeout_remaining != NULL)
-        *usec_timeout_remaining=(tval.tv_sec*1000000)+tval.tv_usec;
+    int nfds = epoll_wait(epoll_fd, epoll_events, EPOLL_MAX_EVENTS, timeout);
 
-    if (ret < 0)
+    if (nfds < 0)
     {
         if (errno == EINTR)
         {
             // select interrupted by signal
-            ret=0;
+            nfds=0;
         }
         else
-            EXCEPTIONSTREAM(error,t2n_server_error,"select error: " << strerror(errno));
+            EXCEPTIONSTREAM(error,t2n_server_error,"epoll error: " << strerror(errno));
     }
 
-    if (ret > 0)
+    if (nfds > 0)
     {
         // we have data pending
-
         // check for new connection
-        if (FD_ISSET (sock, &used_fdset))
+        for (int n=0; n < nfds; ++n)
         {
-            new_connection();
+            if(sock != epoll_events[n].data.fd)
+            {
+                new_connection();
+                continue;
+            }
+            socket_server_connection *ready_client = static_cast<socket_server_connection*>(epoll_events[n].data.ptr);
+            if(ready_client != NULL)
+                ready_client->fill_buffer(timeout);
         }
-
         // check all connections for pending data
         return fill_connection_buffers();
     }
@@ -288,8 +268,9 @@ bool socket_server::fill_connection_buffers()
 /// remove the socket of a connection after the connection has been closed
 void socket_server::remove_connection_socket(int sock)
 {
-    FD_CLR(sock, &connection_set);
-    sockets_set.erase(sock);
+    int r = sockets_set.erase(sock);
+    if (r)
+        remove_from_epoll(sock);
 }
 
 /**
@@ -324,9 +305,9 @@ void socket_server_connection::close()
     }
 }
 
-bool socket_server_connection::fill_buffer(long long usec_timeout,long long* usec_timeout_remaining)
+bool socket_server_connection::fill_buffer(int timeout)
 {
-    bool new_data = socket_handler::fill_buffer(buffer,usec_timeout,usec_timeout_remaining);
+    bool new_data = socket_handler::fill_buffer(buffer, timeout);
     if (new_data)
         reset_timeout();
     return new_data;
index bbba379..09546c5 100644 (file)
@@ -22,6 +22,7 @@ on this file might be covered by the GNU General Public License.
 #ifndef __LIBT2N_SOCKET_SERVER
 #define __LIBT2N_SOCKET_SERVER
 
+#include <sys/epoll.h>
 #include <sys/types.h>
 #include <string>
 #include <set>
@@ -47,7 +48,6 @@ class socket_server : public socket_handler, public server
     friend class socket_server_connection;
 
     private:
-        fd_set connection_set;
         std::string unix_path;
         std::set<int> sockets_set;
 
@@ -55,7 +55,6 @@ class socket_server : public socket_handler, public server
 
         void new_connection();
 
-        bool fill_connection_buffers();
         void remove_connection_socket(int sock);
 
     protected:
@@ -68,7 +67,13 @@ class socket_server : public socket_handler, public server
 
         ~socket_server();
 
-        bool fill_buffer(long long usec_timeout=-1,long long* usec_timeout_remaining=NULL);
+        /** @brief look for new connections and new data in any of the existing connections
+        @param timeout wait until new data is found, max timeout millisecs.
+                -1: wait endless
+                0: return instantly
+        */
+        bool fill_buffer(int timeout);
+        bool fill_connection_buffers();
         std::set<int> get_sockets_set()
             { return sockets_set; };
 };
@@ -83,8 +88,8 @@ class socket_server_connection : public socket_handler, public server_connection
 
     private:
         socket_server_connection(int _sock, socket_type_value _stype, int _timeout)
-           : socket_handler(_sock,_stype), server_connection(_timeout)
-           { }
+                : socket_handler(_sock,_stype), server_connection(_timeout)
+        { }
 
         ~socket_server_connection();
 
@@ -95,9 +100,10 @@ class socket_server_connection : public socket_handler, public server_connection
             { socket_write(data); }
 
     public:
-        bool fill_buffer(long long usec_timeout=-1,long long* usec_timeout_remaining=NULL);
+        bool fill_buffer(int timeout);
 
         virtual void close();
+
 };
 
 }
index 50ec75f..ff083dc 100644 (file)
@@ -45,10 +45,10 @@ client_connection* BasicSocketWrapper::get_connection(void)
     {
         if (socket_type == tcp_s)
             c=std::auto_ptr<socket_client_connection>
-                (new socket_client_connection(port,server,connect_timeout_usec,max_retries,logstream,log_level));
+                (new socket_client_connection(port, server, connect_timeout_millisec, max_retries, logstream, log_level));
         else if (socket_type == unix_s)
             c=std::auto_ptr<socket_client_connection>
-                (new socket_client_connection(path,connect_timeout_usec,max_retries,logstream,log_level));
+                (new socket_client_connection(path, connect_timeout_millisec, max_retries, logstream, log_level));
     }
 
     return c.get();
@@ -95,7 +95,7 @@ bool ReconnectSocketWrapper::handle(command_client* stubBase, boost::function< v
 }
 
 /// return active connection, return a dummy-connection if we can't establish one
-client_connection* ReconnectIgnoreFailureSocketWrapper::get_connection(void)
+client_connection* ReconnectIgnoreFailureSocketWrapper::get_connection()
 {
     client_connection* tmp=BasicSocketWrapper::get_connection();
 
index cf1d385..20abefa 100644 (file)
@@ -38,7 +38,7 @@ namespace libt2n
 /** @brief a basic implementation of ConnectionWrapper
 
     This is a basic version of a ConnectionWrapper which does not do any fancy
-    error handling or anything, it justs executes the regular calls. Use this
+    error handling or anything, it just executes the regular calls. Use this
     wrapper if you only want to use the singleton-feature of T2nSingletonWrapper.
 */
 class BasicSocketWrapper : public ConnectionWrapper
@@ -50,7 +50,7 @@ class BasicSocketWrapper : public ConnectionWrapper
         std::string server;
         int port;
 
-        long long connect_timeout_usec;
+        int connect_timeout_millisec;
         int max_retries;
 
         std::auto_ptr<socket_client_connection> c;
@@ -60,29 +60,29 @@ class BasicSocketWrapper : public ConnectionWrapper
 
     public:
         BasicSocketWrapper(int _port, const std::string& _server="127.0.0.1", 
-            long long _connect_timeout_usec=socket_client_connection::connect_timeout_usec_default, 
+            int _connect_timeout_millisec=socket_client_connection::connect_timeout_millisec_default,
             int _max_retries=socket_client_connection::max_retries_default)
             : ConnectionWrapper(),
               socket_type(tcp_s),
               server(_server),
               port(_port),
-              connect_timeout_usec(_connect_timeout_usec),
+              connect_timeout_millisec(_connect_timeout_millisec),
               max_retries(_max_retries)
             { }
 
         BasicSocketWrapper(const std::string& _path,
-            long long _connect_timeout_usec=socket_client_connection::connect_timeout_usec_default, 
+            int _connect_timeout_millisec=socket_client_connection::connect_timeout_millisec_default,
             int _max_retries=socket_client_connection::max_retries_default)
             : ConnectionWrapper(),
               socket_type(unix_s),
               path(_path),
-              connect_timeout_usec(_connect_timeout_usec),
+              connect_timeout_millisec(_connect_timeout_millisec),
               max_retries(_max_retries)
             { }
 
-        client_connection* get_connection(void);
+        client_connection* get_connection();
 
-        bool connection_established(void)
+        bool connection_established()
             { return (c.get() != NULL); }
 
         void set_logging(std::ostream *_logstream, log_level_values _log_level);
@@ -96,16 +96,18 @@ class BasicSocketWrapper : public ConnectionWrapper
 class ReconnectSocketWrapper : public BasicSocketWrapper
 {
     public:
-        ReconnectSocketWrapper(int _port, const std::string& _server="127.0.0.1", 
-            long long _connect_timeout_usec=socket_client_connection::connect_timeout_usec_default, 
+        explicit ReconnectSocketWrapper(int _port, const std::string& _server="127.0.0.1",
+            int _connect_timeout_millisec=socket_client_connection::connect_timeout_millisec_default,
             int _max_retries=socket_client_connection::max_retries_default)
-            : BasicSocketWrapper(_port,_server,_connect_timeout_usec,_max_retries)
+            : BasicSocketWrapper(_port, _server, _connect_timeout_millisec,
+                                 _max_retries)
             { }
 
-        ReconnectSocketWrapper(const std::string& _path,
-            long long _connect_timeout_usec=socket_client_connection::connect_timeout_usec_default, 
+        explicit ReconnectSocketWrapper(const std::string& _path,
+            int _connect_timeout_millisec=socket_client_connection::connect_timeout_millisec_default,
             int _max_retries=socket_client_connection::max_retries_default)
-            : BasicSocketWrapper(_path,_connect_timeout_usec,_max_retries)
+            : BasicSocketWrapper(_path, _connect_timeout_millisec,
+                                 _max_retries)
             { }
 
         bool handle(command_client* stubBase, boost::function< void() > f);
@@ -123,7 +125,7 @@ class dummy_client_connection : public client_connection
             : client_connection()
             { close(); }
 
-        bool fill_buffer(long long usec_timeout=-1, long long *usec_timeout_remaining=NULL)
+        bool fill_buffer(int millisec_timeout=-1)
             { return false; }
 };
 
@@ -139,16 +141,16 @@ class ReconnectIgnoreFailureSocketWrapper : public ReconnectSocketWrapper
         dummy_client_connection dc;
 
     public:
-        ReconnectIgnoreFailureSocketWrapper(int _port, const std::string& _server="127.0.0.1", 
-            long long _connect_timeout_usec=socket_client_connection::connect_timeout_usec_default, 
+    __attribute__((unused)) explicit ReconnectIgnoreFailureSocketWrapper(int _port, const std::string& _server="127.0.0.1", 
+            int _connect_timeout_millisec=socket_client_connection::connect_timeout_millisec_default,
             int _max_retries=socket_client_connection::max_retries_default)
-            : ReconnectSocketWrapper(_port,_server,_connect_timeout_usec,_max_retries)
+            : ReconnectSocketWrapper(_port, _server, _connect_timeout_millisec, _max_retries)
             { }
 
-        ReconnectIgnoreFailureSocketWrapper(const std::string& _path,
-            long long _connect_timeout_usec=socket_client_connection::connect_timeout_usec_default, 
+        explicit ReconnectIgnoreFailureSocketWrapper(const std::string& _path,
+            int _connect_timeout_millisec=socket_client_connection::connect_timeout_millisec_default,
             int _max_retries=socket_client_connection::max_retries_default)
-            : ReconnectSocketWrapper(_path,_connect_timeout_usec,_max_retries)
+            : ReconnectSocketWrapper(_path, _connect_timeout_millisec, _max_retries)
             { }
 
         client_connection* get_connection(void);
index a7a885d..48ccf5c 100644 (file)
@@ -146,7 +146,7 @@ BOOST_AUTO_TEST_CASE(BadTag)
 
             command_client cc(&sc);
 
-            t2n_exception* ep=cc.get_constuctor_exception();
+            t2n_exception* ep=cc.get_constructor_exception();
 
             string errormsg;
             if (ep)
@@ -205,7 +205,7 @@ BOOST_AUTO_TEST_CASE(BadVersion)
 
             command_client cc(&sc);
 
-            t2n_exception* ep=cc.get_constuctor_exception();
+            t2n_exception* ep=cc.get_constructor_exception();
 
             string errormsg;
             if (ep)
@@ -263,7 +263,7 @@ BOOST_AUTO_TEST_CASE(SeparatorMissing)
 
             command_client cc(&sc);
 
-            t2n_exception* ep=cc.get_constuctor_exception();
+            t2n_exception* ep=cc.get_constructor_exception();
 
             string errormsg;
             if (ep)
@@ -330,7 +330,7 @@ BOOST_AUTO_TEST_CASE(WrongByteOrder)
 
             command_client cc(&sc);
 
-            t2n_exception* ep=cc.get_constuctor_exception();
+            t2n_exception* ep=cc.get_constructor_exception();
 
             string errormsg;
             if (ep)
@@ -386,7 +386,7 @@ BOOST_AUTO_TEST_CASE(OtherServerBig)
 
             command_client cc(&sc);
 
-            t2n_exception* ep=cc.get_constuctor_exception();
+            t2n_exception* ep=cc.get_constructor_exception();
 
             string errormsg;
             if (ep)
@@ -442,7 +442,7 @@ BOOST_AUTO_TEST_CASE(OtherServerSmall)
 
             command_client cc(&sc);
 
-            t2n_exception* ep=cc.get_constuctor_exception();
+            t2n_exception* ep=cc.get_constructor_exception();
 
             string errormsg;
             if (ep)
index 204e741..c03e330 100644 (file)
@@ -221,7 +221,7 @@ BOOST_AUTO_TEST_CASE(ReentrantServer)
 
                 long long maxtime=1000000;
                 while(maxtime > 0)
-                    cs.handle(maxtime,&maxtime);
+                    cs.handle(maxtime);
             }
 
             global_server = NULL;
index 936cc6a..1eb9e5b 100644 (file)
@@ -239,7 +239,7 @@ BOOST_AUTO_TEST_CASE(HelloTimeoutNothing)
             socket_client_connection sc("./socket");
             command_client cc(&sc,1000000,1000000);
 
-            t2n_exception* ep=cc.get_constuctor_exception();
+            t2n_exception* ep=cc.get_constructor_exception();
 
             string errormsg;
             if (ep)
@@ -301,7 +301,7 @@ BOOST_AUTO_TEST_CASE(HelloTimeoutSlowData)
             socket_client_connection sc("./socket");
             command_client cc(&sc,1000000,1000000);
 
-            t2n_exception* ep=cc.get_constuctor_exception();
+            t2n_exception* ep=cc.get_constructor_exception();
 
             string errormsg;
             if (ep)
index 5fedaf5..f7dcb88 100644 (file)
@@ -202,8 +202,8 @@ class cmd_group_x_client : public command_client
 {
     public:
         cmd_group_x_client(libt2n::client_connection *_c,
-         long long _command_timeout_usec=command_timeout_usec_default,
-         long long _hello_timeout_usec=hello_timeout_usec_default)
+         long long _command_timeout_usec=command_timeout_millisec_default,
+         long long _hello_timeout_usec=hello_timeout_millisec_default)
          : libt2n::command_client(_c,_command_timeout_usec,_hello_timeout_usec)
         {}
 
@@ -358,8 +358,8 @@ BOOST_AUTO_TEST_CASE(reconnect_after_close)
     wraptype::set_connection(auto_ptr<ConnectionWrapper>
         (new ReconnectSocketWrapper("./socket")));
 
-    wraptype::get_connection_wrapper()->set_command_timeout_usec(3000000);
-    wraptype::get_connection_wrapper()->set_hello_timeout_usec(3000000);
+    wraptype::get_connection_wrapper()->set_command_timeout_millisec(3000000);
+    wraptype::get_connection_wrapper()->set_hello_timeout_millisec(3000000);
 
     // 42 closes connection on the server side
     t2n_exec(&cmd_group_x_client::serverfunc)(42);
@@ -406,8 +406,8 @@ BOOST_AUTO_TEST_CASE(ignore_handler_reconnects)
     wraptype::set_connection(auto_ptr<ConnectionWrapper>
         (new ReconnectIgnoreFailureSocketWrapper("./socket")));
 
-    wraptype::get_connection_wrapper()->set_command_timeout_usec(3000000);
-    wraptype::get_connection_wrapper()->set_hello_timeout_usec(3000000);
+    wraptype::get_connection_wrapper()->set_command_timeout_millisec(3000000);
+    wraptype::get_connection_wrapper()->set_hello_timeout_millisec(3000000);
 
     // 42 closes connection on the server side
     t2n_exec(&cmd_group_x_client::serverfunc)(42);
@@ -493,7 +493,7 @@ BOOST_AUTO_TEST_CASE(ignore_finds_lateserver)
         // parent
         {
             // wait till server is up
-            sleep(1);
+            sleep(2);
         }
     }