asyn-thread: create a socketpair to wait on

Closes #4157
This commit is contained in:
amkatyal 2019-07-26 21:28:41 +05:30 committed by Daniel Stenberg
parent db0a0dfb0e
commit eb9a604f8d
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
2 changed files with 65 additions and 11 deletions

76
lib/asyn-thread.c Normal file → Executable file
View File

@ -163,6 +163,9 @@ struct thread_sync_data {
char *hostname; /* hostname to resolve, Curl_async.hostname char *hostname; /* hostname to resolve, Curl_async.hostname
duplicate */ duplicate */
int port; int port;
#ifdef HAVE_SOCKETPAIR
curl_socket_t sock_pair[2]; /* socket pair */
#endif
int sock_error; int sock_error;
Curl_addrinfo *res; Curl_addrinfo *res;
#ifdef HAVE_GETADDRINFO #ifdef HAVE_GETADDRINFO
@ -197,6 +200,16 @@ void destroy_thread_sync_data(struct thread_sync_data * tsd)
if(tsd->res) if(tsd->res)
Curl_freeaddrinfo(tsd->res); Curl_freeaddrinfo(tsd->res);
#ifdef HAVE_SOCKETPAIR
/* close socket pair */
if(tsd->sock_pair[0] != CURL_SOCKET_BAD) {
sclose(tsd->sock_pair[0]);
}
if(tsd->sock_pair[1] != CURL_SOCKET_BAD) {
sclose(tsd->sock_pair[1]);
}
#endif
memset(tsd, 0, sizeof(*tsd)); memset(tsd, 0, sizeof(*tsd));
} }
@ -230,6 +243,14 @@ int init_thread_sync_data(struct thread_data * td,
Curl_mutex_init(tsd->mtx); Curl_mutex_init(tsd->mtx);
#ifdef HAVE_SOCKETPAIR
/* create socket pair */
if(socketpair(AF_LOCAL, SOCK_STREAM, 0, &tsd->sock_pair[0]) < 0) {
tsd->sock_pair[0] = CURL_SOCKET_BAD;
tsd->sock_pair[1] = CURL_SOCKET_BAD;
goto err_exit;
}
#endif
tsd->sock_error = CURL_ASYNC_SUCCESS; tsd->sock_error = CURL_ASYNC_SUCCESS;
/* Copying hostname string because original can be destroyed by parent /* Copying hostname string because original can be destroyed by parent
@ -276,6 +297,9 @@ static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg)
struct thread_data *td = tsd->td; struct thread_data *td = tsd->td;
char service[12]; char service[12];
int rc; int rc;
#ifdef HAVE_SOCKETPAIR
char buf[1];
#endif
msnprintf(service, sizeof(service), "%d", tsd->port); msnprintf(service, sizeof(service), "%d", tsd->port);
@ -298,6 +322,16 @@ static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg)
free(td); free(td);
} }
else { else {
#ifdef HAVE_SOCKETPAIR
if(tsd->sock_pair[1] != CURL_SOCKET_BAD) {
/* DNS has been resolved, signal client task */
buf[0] = 1;
if(write(tsd->sock_pair[1], buf, sizeof(buf)) < 0) {
/* update sock_erro to errno */
tsd->sock_error = SOCKERRNO;
}
}
#endif
tsd->done = 1; tsd->done = 1;
Curl_mutex_release(tsd->mtx); Curl_mutex_release(tsd->mtx);
} }
@ -595,23 +629,43 @@ int Curl_resolver_getsock(struct connectdata *conn,
curl_socket_t *socks, curl_socket_t *socks,
int numsocks) int numsocks)
{ {
int ret_val = 0;
time_t milli; time_t milli;
timediff_t ms; timediff_t ms;
struct Curl_easy *data = conn->data; struct Curl_easy *data = conn->data;
struct resdata *reslv = (struct resdata *)data->state.resolver; struct resdata *reslv = (struct resdata *)data->state.resolver;
#ifdef HAVE_SOCKETPAIR
struct thread_data *td = (struct thread_data*)conn->async.os_specific;
int loop_idx;
#else
(void)socks; (void)socks;
(void)numsocks; (void)numsocks;
ms = Curl_timediff(Curl_now(), reslv->start); #endif
if(ms < 3)
milli = 0; #ifdef HAVE_SOCKETPAIR
else if(ms <= 50) if(td) {
milli = ms/3; /* return read fd to client for polling the DNS resolution status */
else if(ms <= 250) socks[0] = td->tsd.sock_pair[0];
milli = 50; ret_val = GETSOCK_READSOCK(0);
else }
milli = 200; else {
Curl_expire(data, milli, EXPIRE_ASYNC_NAME); #endif
return 0; ms = Curl_timediff(Curl_now(), reslv->start);
if(ms < 3)
milli = 0;
else if(ms <= 50)
milli = ms/3;
else if(ms <= 250)
milli = 50;
else
milli = 200;
Curl_expire(data, milli, EXPIRE_ASYNC_NAME);
#ifdef HAVE_SOCKETPAIR
}
#endif
return ret_val;
} }
#ifndef HAVE_GETADDRINFO #ifndef HAVE_GETADDRINFO

0
lib/multi.c Normal file → Executable file
View File