On Mon, 14 Jun 2010, Daniel Stenberg wrote:

In your patch, it becomes the longest time select() will ever wait for action, but is that really the time a user wants to specify? Won't a user rather want to specify the longest time a particular libssh2 function is allowed to wait or similar?

BTW, to further this discussion I've adapted Jan's work against current git to show the current state of the work.

The timeout is in this case simply "the maximum time libssh2 will ever wait for data on the socket".

I'll appreciate further thoughts and opinions.

--

 / daniel.haxx.se
diff --git a/include/libssh2.h b/include/libssh2.h
index 95c557b..ce03143 100644
--- a/include/libssh2.h
+++ b/include/libssh2.h
@@ -422,6 +422,20 @@ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session,
 
 LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session);
 
+/* libssh2_session_get_timeout
+ *
+ * Returns a session's timoout
+ */
+LIBSSH2_API int libssh2_session_get_timeout(LIBSSH2_SESSION *session);
+
+/* libssh2_session_set_timeout
+ *
+ * Set a session's timeout (in msec) for blocking mode,
+ * or 0 to disable timeouts.
+ */
+LIBSSH2_API void libssh2_session_set_timeout(LIBSSH2_SESSION *session,
+                                             int timeout);
+
 LIBSSH2_API const char *libssh2_hostkey_hash(LIBSSH2_SESSION *session,
                                              int hash_type);
 
diff --git a/src/libssh2_priv.h b/src/libssh2_priv.h
index 54d4d16..fa9ef79 100644
--- a/src/libssh2_priv.h
+++ b/src/libssh2_priv.h
@@ -735,6 +735,9 @@ struct _LIBSSH2_SESSION
     int socket_prev_blockstate; /* stores the state of the socket blockiness
                                    when libssh2_session_startup() is called */
 
+    /* Timeout used when blocking API behavior is active */
+    int api_timeout;
+
     /* Error tracking */
     const char *err_msg;
     int err_code;
diff --git a/src/session.c b/src/session.c
index f6498e4..c6a6867 100644
--- a/src/session.c
+++ b/src/session.c
@@ -540,16 +540,22 @@ libssh2_session_callback_set(LIBSSH2_SESSION * session,
 int _libssh2_wait_socket(LIBSSH2_SESSION *session)
 {
     int rc;
-    int seconds_to_next;
+    int ms_to_next;
     int dir;
 
-    rc = libssh2_keepalive_send (session, &seconds_to_next);
+    rc = libssh2_keepalive_send (session, &ms_to_next);
     if (rc < 0)
         return rc;
     else {
+        ms_to_next *= 1000; /* convert the timeout to milliseconds */
+
         /* figure out what to wait for */
         dir = libssh2_session_block_directions(session);
 
+        if (session->api_timeout &&
+            (session->api_timeout < ms_to_next))
+            ms_to_next = session->api_timeout;
+
         {
 #ifdef HAVE_POLL
             struct pollfd sockets[1];
@@ -564,7 +570,7 @@ int _libssh2_wait_socket(LIBSSH2_SESSION *session)
             if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
                 sockets[0].events |= POLLOUT;
 
-            rc = poll(sockets, 1, seconds_to_next ? seconds_to_next / 1000 : -1);
+            rc = poll(sockets, 1, ms_to_next ? ms_to_next : -1);
 #else
             fd_set rfd;
             fd_set wfd;
@@ -572,8 +578,9 @@ int _libssh2_wait_socket(LIBSSH2_SESSION *session)
             fd_set *readfd = NULL;
             struct timeval tv;
 
-            tv.tv_sec = seconds_to_next;
-            tv.tv_usec = 0;
+            tv.tv_sec = ms_to_next/1000;  /* full seconds */
+            ms_to_next -= tv.tv_sec*1000; /* remove seconds we stored */
+            tv.tv_usec = ms_to_next*1000; /* remainder turned into us */
 
             if(dir & LIBSSH2_SESSION_BLOCK_INBOUND) {
                 FD_ZERO(&rfd);
@@ -590,7 +597,7 @@ int _libssh2_wait_socket(LIBSSH2_SESSION *session)
             /* Note that this COULD be made to use a timeout that perhaps
                could be customizable by the app or something... */
             rc = select(session->socket_fd + 1, readfd, writefd, NULL,
-                        seconds_to_next ? &tv : NULL);
+                        ms_to_next ? &tv : NULL);
 #endif
         }
     }
@@ -1245,6 +1252,27 @@ libssh2_session_get_blocking(LIBSSH2_SESSION * session)
     return session->api_block_mode;
 }
 
+/* libssh2_session_set_timeout
+ *
+ * Set a session's timeout (in msec) for blocking mode,
+ * or 0 to disable timeouts.
+ */
+LIBSSH2_API void
+libssh2_session_set_timeout(LIBSSH2_SESSION *session, int timeout)
+{
+    session->api_timeout = timeout;
+}
+
+/* libssh2_session_get_timeout
+ *
+ * Returns a session's timeout, or 0 if disabled
+ */
+LIBSSH2_API int
+libssh2_session_get_timeout(LIBSSH2_SESSION *session)
+{
+    return session->api_timeout;
+}
+
 /*
  * libssh2_poll_channel_read
  *
_______________________________________________
libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel

Reply via email to