Jacek Caban : wininet: Use blocking_mode_t instead of flags in NETCON_recv.

Alexandre Julliard julliard at winehq.org
Wed Mar 5 14:12:31 CST 2014


Module: wine
Branch: master
Commit: 0767e06044abb17e56e4c4fca4f8b73ccfb18c12
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=0767e06044abb17e56e4c4fca4f8b73ccfb18c12

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Mar  5 18:27:36 2014 +0100

wininet: Use blocking_mode_t instead of flags in NETCON_recv.

---

 dlls/wininet/http.c          |   23 +++++++++++------------
 dlls/wininet/internet.h      |    9 +++++++--
 dlls/wininet/netconnection.c |   34 +++++++++++++++++++++++++++++++---
 3 files changed, 49 insertions(+), 17 deletions(-)

diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c
index 1232d35..62faadd 100644
--- a/dlls/wininet/http.c
+++ b/dlls/wininet/http.c
@@ -379,12 +379,6 @@ static LPHTTPHEADERW HTTP_GetHeader(http_request_t *req, LPCWSTR head)
         return &req->custHeaders[HeaderIndex];
 }
 
-typedef enum {
-    BLOCKING_ALLOW,
-    BLOCKING_DISALLOW,
-    BLOCKING_WAITALL
-} blocking_mode_t;
-
 struct data_stream_vtbl_t {
     DWORD (*get_avail_data)(data_stream_t*,http_request_t*);
     BOOL (*end_of_data)(data_stream_t*,http_request_t*);
@@ -2497,7 +2491,7 @@ static DWORD read_more_data( http_request_t *req, int maxlen )
     if (maxlen == -1) maxlen = sizeof(req->read_buf);
 
     res = NETCON_recv( req->netconn, req->read_buf + req->read_size,
-                       maxlen - req->read_size, 0, &len );
+                       maxlen - req->read_size, BLOCKING_ALLOW, &len );
     if(res == ERROR_SUCCESS)
         req->read_size += len;
 
@@ -2654,10 +2648,15 @@ static DWORD netconn_read(data_stream_t *stream, http_request_t *req, BYTE *buf,
     }
 
     if(size && is_valid_netconn(req->netconn)) {
-        if((res = NETCON_recv(req->netconn, buf, size, blocking_mode == BLOCKING_WAITALL ? MSG_WAITALL : 0, &len)))
+        if((res = NETCON_recv(req->netconn, buf, size, blocking_mode, &len))) {
             len = 0;
-        if(!len)
+            if(blocking_mode == BLOCKING_DISALLOW && res == WSAEWOULDBLOCK)
+                res = ERROR_SUCCESS;
+            else
+                netconn_stream->content_length = netconn_stream->content_read;
+        }else if(!len) {
             netconn_stream->content_length = netconn_stream->content_read;
+        }
     }
 
     netconn_stream->content_read += *read = len;
@@ -2680,7 +2679,7 @@ static BOOL netconn_drain_content(data_stream_t *stream, http_request_t *req)
         if(!avail)
             return FALSE;
 
-        if(NETCON_recv(req->netconn, buf, min(avail, sizeof(buf)), 0, &len) != ERROR_SUCCESS)
+        if(NETCON_recv(req->netconn, buf, min(avail, sizeof(buf)), BLOCKING_ALLOW, &len) != ERROR_SUCCESS)
             return FALSE;
 
         netconn_stream->content_read += len;
@@ -2720,7 +2719,7 @@ static DWORD read_more_chunked_data(chunked_stream_t *stream, http_request_t *re
     if (maxlen == -1) maxlen = sizeof(stream->buf);
 
     res = NETCON_recv( req->netconn, stream->buf + stream->buf_size,
-                       maxlen - stream->buf_size, 0, &len );
+                       maxlen - stream->buf_size, BLOCKING_ALLOW, &len );
     if(res == ERROR_SUCCESS)
         stream->buf_size += len;
 
@@ -2845,7 +2844,7 @@ static DWORD chunked_read(data_stream_t *stream, http_request_t *req, BYTE *buf,
                     break;
             }
 
-            res = NETCON_recv(req->netconn, (char *)buf+ret_read, read_bytes, 0, (int*)&read_bytes);
+            res = NETCON_recv(req->netconn, (char *)buf+ret_read, read_bytes, BLOCKING_ALLOW, (int*)&read_bytes);
             if(res != ERROR_SUCCESS)
                 break;
         }
diff --git a/dlls/wininet/internet.h b/dlls/wininet/internet.h
index 28af0f7..a641340 100644
--- a/dlls/wininet/internet.h
+++ b/dlls/wininet/internet.h
@@ -438,14 +438,19 @@ VOID INTERNET_SendCallback(object_header_t *hdr, DWORD_PTR dwContext,
                            DWORD dwStatusInfoLength) DECLSPEC_HIDDEN;
 BOOL INTERNET_FindProxyForProtocol(LPCWSTR szProxy, LPCWSTR proto, WCHAR *foundProxy, DWORD *foundProxyLen) DECLSPEC_HIDDEN;
 
+typedef enum {
+    BLOCKING_ALLOW,
+    BLOCKING_DISALLOW,
+    BLOCKING_WAITALL
+} blocking_mode_t;
+
 DWORD create_netconn(BOOL,server_t*,DWORD,BOOL,DWORD,netconn_t**) DECLSPEC_HIDDEN;
 void free_netconn(netconn_t*) DECLSPEC_HIDDEN;
 void NETCON_unload(void) DECLSPEC_HIDDEN;
 DWORD NETCON_secure_connect(netconn_t*,server_t*) DECLSPEC_HIDDEN;
 DWORD NETCON_send(netconn_t *connection, const void *msg, size_t len, int flags,
 		int *sent /* out */) DECLSPEC_HIDDEN;
-DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, int flags,
-		int *recvd /* out */) DECLSPEC_HIDDEN;
+DWORD NETCON_recv(netconn_t*,void*,size_t,blocking_mode_t,int*) DECLSPEC_HIDDEN;
 BOOL NETCON_query_data_available(netconn_t *connection, DWORD *available) DECLSPEC_HIDDEN;
 BOOL NETCON_is_alive(netconn_t*) DECLSPEC_HIDDEN;
 LPCVOID NETCON_GetCert(netconn_t *connection) DECLSPEC_HIDDEN;
diff --git a/dlls/wininet/netconnection.c b/dlls/wininet/netconnection.c
index 86c9b08..4c97924 100644
--- a/dlls/wininet/netconnection.c
+++ b/dlls/wininet/netconnection.c
@@ -491,6 +491,14 @@ int sock_get_error( int err )
     return err;
 }
 
+static void set_socket_blocking(int socket, blocking_mode_t mode)
+{
+#if defined(__MINGW32__) || defined (_MSC_VER)
+    ULONG arg = mode == BLOCKING_DISALLOW;
+    ioctlsocket(socket, FIONBIO, &arg);
+#endif
+}
+
 static DWORD netcon_secure_connect_setup(netconn_t *connection, BOOL compat_mode)
 {
     SecBuffer out_buf = {0, SECBUFFER_TOKEN, NULL}, in_bufs[2] = {{0, SECBUFFER_TOKEN}, {0, SECBUFFER_EMPTY}};
@@ -845,7 +853,7 @@ static BOOL read_ssl_chunk(netconn_t *conn, void *buf, SIZE_T buf_size, SIZE_T *
  * Basically calls 'recv()' unless we should use SSL
  * number of chars received is put in *recvd
  */
-DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, int flags, int *recvd)
+DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, blocking_mode_t mode, int *recvd)
 {
     *recvd = 0;
     if (!len)
@@ -853,6 +861,22 @@ DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, int flags, int *
 
     if (!connection->secure)
     {
+        int flags = 0;
+
+        switch(mode) {
+        case BLOCKING_ALLOW:
+            break;
+        case BLOCKING_DISALLOW:
+#ifdef MSG_DONTWAIT
+            flags = MSG_DONTWAIT;
+#endif
+            break;
+        case BLOCKING_WAITALL:
+            flags = MSG_WAITALL;
+            break;
+        }
+
+        set_socket_blocking(connection->socket, mode);
 	*recvd = recv(connection->socket, buf, len, flags);
 	return *recvd == -1 ? sock_get_error(errno) :  ERROR_SUCCESS;
     }
@@ -872,12 +896,16 @@ DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, int flags, int *
                 connection->peek_msg_mem = connection->peek_msg = NULL;
             }
             /* check if we have enough data from the peek buffer */
-            if(!(flags & MSG_WAITALL) || size == len) {
+            if(mode != BLOCKING_WAITALL || size == len) {
                 *recvd = size;
                 return ERROR_SUCCESS;
             }
         }
 
+        if(mode == BLOCKING_DISALLOW)
+            return WSAEWOULDBLOCK; /* FIXME: We can do better */
+        set_socket_blocking(connection->socket, BLOCKING_ALLOW);
+
         do {
             res = read_ssl_chunk(connection, (BYTE*)buf+size, len-size, &cread, &eof);
             if(!res) {
@@ -893,7 +921,7 @@ DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, int flags, int *
             }
 
             size += cread;
-        }while(!size || ((flags & MSG_WAITALL) && size < len));
+        }while(!size || (mode == BLOCKING_WAITALL && size < len));
 
         TRACE("received %ld bytes\n", size);
         *recvd = size;




More information about the wine-cvs mailing list