mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
multi_socket: react on socket close immediately
As a remedy to the problem when a socket gets closed and a new one is opened with the same file descriptor number and as a result multi.c:singlesocket() doesn't detect the difference, the new function Curl_multi_closed() gets told when a socket is closed so that it can be removed from the socket hash. When the old one has been removed, a new socket should be detected fine by the singlesocket() on next invoke. Bug: http://curl.haxx.se/bug/view.cgi?id=1248 Reported-by: Erik Johansson
This commit is contained in:
parent
a9f5ad0e2a
commit
88c5c63ffc
@ -1251,7 +1251,13 @@ int Curl_closesocket(struct connectdata *conn,
|
||||
else
|
||||
return conn->fclosesocket(conn->closesocket_client, sock);
|
||||
}
|
||||
return sclose(sock);
|
||||
sclose(sock);
|
||||
|
||||
if(conn)
|
||||
/* tell the multi-socket code about this */
|
||||
Curl_multi_closed(conn, sock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
33
lib/multi.c
33
lib/multi.c
@ -2051,6 +2051,39 @@ static void singlesocket(struct Curl_multi *multi,
|
||||
easy->numsocks = num;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_multi_closed()
|
||||
*
|
||||
* Used by the connect code to tell the multi_socket code that one of the
|
||||
* sockets we were using have just been closed. This function will then
|
||||
* remove it from the sockethash for this handle to make the multi_socket API
|
||||
* behave properly, especially for the case when libcurl will create another
|
||||
* socket again and it gets the same file descriptor number.
|
||||
*/
|
||||
|
||||
void Curl_multi_closed(struct connectdata *conn, curl_socket_t s)
|
||||
{
|
||||
struct Curl_multi *multi = conn->data->multi;
|
||||
if(multi) {
|
||||
/* this is set if this connection is part of a handle that is added to
|
||||
a multi handle, and only then this is necessary */
|
||||
struct Curl_sh_entry *entry =
|
||||
Curl_hash_pick(multi->sockhash, (char *)&s, sizeof(s));
|
||||
|
||||
if(entry) {
|
||||
if(multi->socket_cb)
|
||||
multi->socket_cb(conn->data, s, CURL_POLL_REMOVE,
|
||||
multi->socket_userp,
|
||||
entry->socketp);
|
||||
|
||||
/* now remove it from the socket hash */
|
||||
sh_delentry(multi->sockhash, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* add_next_timeout()
|
||||
*
|
||||
|
@ -83,4 +83,16 @@ struct curl_llist *Curl_multi_pipelining_server_bl(struct Curl_multi *multi);
|
||||
/* Return the value of the CURLMOPT_MAX_TOTAL_CONNECTIONS option */
|
||||
size_t Curl_multi_max_total_connections(struct Curl_multi *multi);
|
||||
|
||||
/*
|
||||
* Curl_multi_closed()
|
||||
*
|
||||
* Used by the connect code to tell the multi_socket code that one of the
|
||||
* sockets we were using have just been closed. This function will then
|
||||
* remove it from the sockethash for this handle to make the multi_socket API
|
||||
* behave properly, especially for the case when libcurl will create another
|
||||
* socket again and it gets the same file descriptor number.
|
||||
*/
|
||||
|
||||
void Curl_multi_closed(struct connectdata *conn, curl_socket_t s);
|
||||
|
||||
#endif /* HEADER_CURL_MULTIIF_H */
|
||||
|
Loading…
Reference in New Issue
Block a user