On Fri, 21 Aug 2009, Daniel Stenberg wrote:

Okay, here's a first rough patch that shows a little what I had in mind. It should be improved and cleaned up, and I didn't even test it with SFTP or anything - I just ran a few hundred test cases that seemed to all work fine still.

Did I say it is rough? :-)

Here's a minor update that should make pause and bandwidth limiting etc to still work too.

--

 / daniel.haxx.se
Index: lib/ssh.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/ssh.c,v
retrieving revision 1.136
diff -u -r1.136 ssh.c
--- lib/ssh.c	23 Jul 2009 02:15:00 -0000	1.136
+++ lib/ssh.c	21 Aug 2009 12:18:40 -0000
@@ -2291,6 +2291,8 @@
     /* It didn't block or libssh2 didn't reveal in which direction, put back
        the original set */
     sshc->waitfor = sshc->orig_waitfor;
+
+  conn->data->req.waitfor = sshc->waitfor;
 }
 #else
   /* no libssh2 directional support so we simply don't know */
Index: lib/transfer.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/transfer.c,v
retrieving revision 1.436
diff -u -r1.436 transfer.c
--- lib/transfer.c	21 Aug 2009 12:01:36 -0000	1.436
+++ lib/transfer.c	21 Aug 2009 12:18:41 -0000
@@ -1640,6 +1640,7 @@
   struct SingleRequest *k = &data->req;
   CURLcode result;
   int didwhat=0;
+  int keepon;
 
   curl_socket_t fd_read;
   curl_socket_t fd_write;
@@ -1647,27 +1648,43 @@
 
   conn->cselect_bits = 0;
 
+  /*
+   * Theory:
+   *
+   * k->keepon holds the bits for the generic direction of the transfer. It
+   * means a download will have KEEP_RECV set. An upload has KEEP_SEND. Both
+   * can be set, like when you upload HTTP and expects to receive as well.
+   *
+   * Some protocols have both read and write during both download and upload.
+   * The 'waitfor' bits then come into play. If no waitfor bit is set, we use
+   * the keepon bits but if waitfor is set those are in control.
+   *
+   */
+  keepon = k->keepon;
+
+  if(k->waitfor) {
+    /* if waitfor is set, get the RECV and SEND bits from that but keep the
+       other bits */
+    keepon &= ~ (KEEP_RECV|KEEP_SEND);
+    keepon |= k->waitfor & (KEEP_RECV|KEEP_SEND);
+  }
+
   /* only use the proper socket if the *_HOLD bit is not set simultaneously as
      then we are in rate limiting state in that transfer direction */
 
-  if((k->keepon & KEEP_RECVBITS) == KEEP_RECV) {
+  if((keepon & KEEP_RECVBITS) == KEEP_RECV)
     fd_read = conn->sockfd;
-#if defined(USE_LIBSSH2)
-    if(conn->protocol & (PROT_SCP|PROT_SFTP))
-      select_res |= CURL_CSELECT_IN;
-#endif /* USE_LIBSSH2 */
-  } else
+  else
     fd_read = CURL_SOCKET_BAD;
 
-  if((k->keepon & KEEP_SENDBITS) == KEEP_SEND)
+  if((keepon & KEEP_SENDBITS) == KEEP_SEND)
     fd_write = conn->writesockfd;
   else
     fd_write = CURL_SOCKET_BAD;
 
-   if(!select_res) { /* Call for select()/poll() only, if read/write/error
-                         status is not known. */
-       select_res = Curl_socket_ready(fd_read, fd_write, 0);
-   }
+  if(!select_res)
+    /* Call select()/poll() only if read/write/error status is not known. */
+    select_res = Curl_socket_ready(fd_read, fd_write, 0);
 
   if(select_res == CURL_CSELECT_ERR) {
     failf(data, "select/poll returned error");
@@ -1677,18 +1694,16 @@
   /* We go ahead and do a read if we have a readable socket or if
      the stream was rewound (in which case we have data in a
      buffer) */
-  if((k->keepon & KEEP_RECV) &&
+  if((keepon & KEEP_RECV) &&
      ((select_res & CURL_CSELECT_IN) || conn->bits.stream_was_rewound)) {
-
     result = readwrite_data(data, conn, k, &didwhat, done);
     if(result || *done)
       return result;
   }
 
   /* If we still have writing to do, we check if we have a writable socket. */
-  if((k->keepon & KEEP_SEND) && (select_res & CURL_CSELECT_OUT)) {
+  if((keepon & KEEP_SEND) && (select_res & CURL_CSELECT_OUT)) {
     /* write */
-
     result = readwrite_upload(data, conn, k, &didwhat);
     if(result)
       return result;
Index: lib/urldata.h
===================================================================
RCS file: /cvsroot/curl/curl/lib/urldata.h,v
retrieving revision 1.417
diff -u -r1.417 urldata.h
--- lib/urldata.h	21 Aug 2009 07:11:20 -0000	1.417
+++ lib/urldata.h	21 Aug 2009 12:18:41 -0000
@@ -784,6 +784,7 @@
   char *uploadbuf;
   curl_socket_t maxfd;
 
+  int waitfor;
   int keepon;
 
   bool upload_done; /* set to TRUE when doing chunked transfer-encoding upload

Reply via email to