Speed problem - smbclient doesn't send duplicate ACKs in case of pacekt loss

Jeremy Allison jra at samba.org
Thu Jan 6 00:15:22 GMT 2005


On Tue, Jan 04, 2005 at 12:46:17AM -0500, Derrell.Lipman at UnwiredUniverse.com wrote:
> 
> - lib/util.c and lib/select.c

Your change to lib/util.c depends on nanosleep - a linux-only function. I'll
add this with a configure.in test.

>   * In an application with signals, it was possible for functions to block
>     indefinitely while awaiting timeouts.  This patch ensures that if a system
>     call with a timeout is aborted and needs to be restarted, it is restarted
>     with a timeout which is adjusted for the amount of time already waited.

This is correct, but I think slightly less efficient than it could be, as it
does 2 gettimeofday calls per select. Can you give me an opinion on this
version, which I think does the same but with only one gettimeofday call ?

Thanks,

	Jeremy.

Index: lib/select.c
===================================================================
--- lib/select.c        (revision 4543)
+++ lib/select.c        (working copy)
@@ -128,12 +128,24 @@
 {
        int ret;
        fd_set *readfds2, readfds_buf, *writefds2, writefds_buf, *errorfds2, errorfds_buf;
-       struct timeval tval2, *ptval;
+       struct timeval tval2, *ptval, end_time;
  
        readfds2 = (readfds ? &readfds_buf : NULL);
        writefds2 = (writefds ? &writefds_buf : NULL);
        errorfds2 = (errorfds ? &errorfds_buf : NULL);
        ptval = (tval ? &tval2 : NULL);
+       if (tval) {
+               GetTimeOfDay(&end_time);
+               end_time.tv_sec += tval->tv_sec;
+               end_time.tv_usec += tval->tv_usec;
+               end_time.tv_sec += end_time.tv_usec / 1000000;
+               end_time.tv_usec %= 1000000;
+               errno = 0;
+               tval2 = *tval;
+               ptval = &tval2;
+       } else {
+               ptval = NULL;
+       }
  
        do {
                if (readfds)
@@ -142,9 +154,20 @@
                        writefds_buf = *writefds;
                if (errorfds)
                        errorfds_buf = *errorfds;
-               if (tval)
-                       tval2 = *tval;
+               if (ptval && (errno == EINTR)) {
+                       struct timeval now_time;
+                       SMB_BIG_INT tdif;
  
+                       GetTimeOfDay(&now_time);
+                       tdif = usec_time_diff(&end_time, &now_time);
+                       if (tdif <= 0) {
+                               ret = 0; /* time expired. */
+                               break;
+                       }
+                       ptval->tv_sec = tdif / 1000000;
+                       ptval->tv_usec = tdif % 1000000;
+               }
+
                ret = sys_select(maxfd, readfds2, writefds2, errorfds2, ptval);
        } while (ret == -1 && errno == EINTR);



More information about the samba-technical mailing list