From: Paul Gofman pgofman@codeweavers.com
--- dlls/winhttp/net.c | 5 ++++- dlls/winhttp/request.c | 16 ++++++++-------- dlls/winhttp/winhttp_private.h | 3 ++- 3 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/dlls/winhttp/net.c b/dlls/winhttp/net.c index a3ccf40cb65..76700a9a32a 100644 --- a/dlls/winhttp/net.c +++ b/dlls/winhttp/net.c @@ -214,6 +214,7 @@ DWORD netconn_create( struct hostdata *host, const struct sockaddr_storage *sock winsock_init();
if (!(conn = calloc( 1, sizeof(*conn) ))) return ERROR_OUTOFMEMORY; + conn->refs = 1; conn->host = host; conn->sockaddr = *sockaddr; if ((conn->socket = WSASocketW( sockaddr->ss_family, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED )) == -1) @@ -277,8 +278,10 @@ DWORD netconn_create( struct hostdata *host, const struct sockaddr_storage *sock return ERROR_SUCCESS; }
-void netconn_close( struct netconn *conn ) +void netconn_release( struct netconn *conn ) { + if (InterlockedDecrement( &conn->refs )) return; + TRACE( "Closing connection %p.\n", conn ); if (conn->secure) { free( conn->peek_msg_mem ); diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c index e977070e87c..dbee446783a 100644 --- a/dlls/winhttp/request.c +++ b/dlls/winhttp/request.c @@ -1449,7 +1449,7 @@ static void CALLBACK connection_collector( TP_CALLBACK_INSTANCE *instance, void { TRACE("freeing %p\n", netconn); list_remove(&netconn->entry); - netconn_close(netconn); + netconn_release(netconn); } else remaining_connections++; } @@ -1591,7 +1591,7 @@ static DWORD open_connection( struct request *request )
if (netconn_is_alive( netconn )) break; TRACE("connection %p no longer alive, closing\n", netconn); - netconn_close( netconn ); + netconn_release( netconn ); netconn = NULL; }
@@ -1654,7 +1654,7 @@ static DWORD open_connection( struct request *request ) { request->netconn = NULL; free( addressW ); - netconn_close( netconn ); + netconn_release( netconn ); return ret; } } @@ -1668,7 +1668,7 @@ static DWORD open_connection( struct request *request ) { request->netconn = NULL; free( addressW ); - netconn_close( netconn ); + netconn_release( netconn ); return ret; } } @@ -1687,7 +1687,7 @@ static DWORD open_connection( struct request *request ) if (netconn->secure && !(request->server_cert = netconn_get_certificate( netconn ))) { free( addressW ); - netconn_close( netconn ); + netconn_release( netconn ); return ERROR_WINHTTP_SECURE_FAILURE; }
@@ -1705,7 +1705,7 @@ void close_connection( struct request *request ) if (!request->netconn) return;
send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION, 0, 0 ); - netconn_close( request->netconn ); + netconn_release( request->netconn ); request->netconn = NULL; send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED, 0, 0 ); } @@ -1884,7 +1884,7 @@ static void finished_reading( struct request *request ) else if (!wcscmp( request->version, L"HTTP/1.0" )) close = TRUE;
if (close) - netconn_close( request->netconn ); + netconn_release( request->netconn ); else cache_connection( request->netconn ); request->netconn = NULL; @@ -2715,7 +2715,7 @@ static DWORD handle_redirect( struct request *request, DWORD status ) goto end; }
- netconn_close( request->netconn ); + netconn_release( request->netconn ); request->netconn = NULL; request->content_length = request->content_read = 0; request->read_pos = request->read_size = 0; diff --git a/dlls/winhttp/winhttp_private.h b/dlls/winhttp/winhttp_private.h index a6946d5e366..211e2134012 100644 --- a/dlls/winhttp/winhttp_private.h +++ b/dlls/winhttp/winhttp_private.h @@ -106,6 +106,7 @@ struct connect struct netconn { struct list entry; + LONG refs; int socket; struct sockaddr_storage sockaddr; BOOL secure; /* SSL active on connection? */ @@ -370,7 +371,7 @@ void close_connection( struct request * ) DECLSPEC_HIDDEN; void init_queue( struct queue *queue ) DECLSPEC_HIDDEN; void stop_queue( struct queue * ) DECLSPEC_HIDDEN;
-void netconn_close( struct netconn * ) DECLSPEC_HIDDEN; +void netconn_release( struct netconn * ) DECLSPEC_HIDDEN; DWORD netconn_create( struct hostdata *, const struct sockaddr_storage *, int, struct netconn ** ) DECLSPEC_HIDDEN; void netconn_unload( void ) DECLSPEC_HIDDEN; ULONG netconn_query_data_available( struct netconn * ) DECLSPEC_HIDDEN;