* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
#include "curl_setup.h"
+/***********************************************************************
+ * Only for threaded name resolves builds
+ **********************************************************************/
+#ifdef CURLRES_THREADED
+
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#include "curl_memory.h"
#include "memdebug.h"
-/***********************************************************************
- * Only for threaded name resolves builds
- **********************************************************************/
-#ifdef CURLRES_THREADED
-
/*
* Curl_resolver_global_init()
* Called from curl_global_init() to initialize global resolver environment.
tsd->td = td;
tsd->port = port;
+ /* Treat the request as done until the thread actually starts so any early
+ * cleanup gets done properly.
+ */
+ tsd->done = 1;
#ifdef HAVE_GETADDRINFO
DEBUGASSERT(hints);
tsd->hints = *hints;
const struct addrinfo *hints)
{
struct thread_data *td = calloc(1, sizeof(struct thread_data));
- int err = RESOLVER_ENOMEM;
+ int err = ENOMEM;
conn->async.os_specific = (void *)td;
if(!td)
- goto err_exit;
+ goto errno_exit;
conn->async.port = port;
conn->async.done = FALSE;
conn->async.dns = NULL;
td->thread_hnd = curl_thread_t_null;
- if(!init_thread_sync_data(td, hostname, port, hints))
- goto err_exit;
+ if(!init_thread_sync_data(td, hostname, port, hints)) {
+ conn->async.os_specific = NULL;
+ free(td);
+ goto errno_exit;
+ }
free(conn->async.hostname);
conn->async.hostname = strdup(hostname);
if(!conn->async.hostname)
goto err_exit;
+ /* The thread will set this to 1 when complete. */
+ td->tsd.done = 0;
+
#ifdef HAVE_GETADDRINFO
td->thread_hnd = Curl_thread_create(getaddrinfo_thread, &td->tsd);
#else
#endif
if(!td->thread_hnd) {
-#ifndef _WIN32_WCE
+ /* The thread never started, so mark it as done here for proper cleanup. */
+ td->tsd.done = 1;
err = errno;
-#endif
goto err_exit;
}
err_exit:
destroy_async_data(&conn->async);
- SET_ERRNO(err);
-
+ errno_exit:
+ errno = err;
return FALSE;
}
}
else {
/* poll for name lookup done with exponential backoff up to 250ms */
- time_t elapsed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
+ timediff_t elapsed = Curl_timediff(Curl_now(),
+ data->progress.t_startsingle);
if(elapsed < 0)
elapsed = 0;
td->poll_interval = 250;
td->interval_end = elapsed + td->poll_interval;
- Curl_expire(conn->data, td->poll_interval);
+ Curl_expire(conn->data, td->poll_interval, EXPIRE_ASYNC_NAME);
}
return CURLE_OK;
int *waitp)
{
struct addrinfo hints;
- struct in_addr in;
Curl_addrinfo *res;
int error;
char sbuf[12];
int pf = PF_INET;
-#ifdef CURLRES_IPV6
- struct in6_addr in6;
-#endif /* CURLRES_IPV6 */
*waitp = 0; /* default to synchronous response */
#ifndef USE_RESOLVE_ON_IPS
- /* First check if this is an IPv4 address string */
- if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
- /* This is a dotted IP address 123.123.123.123-style */
- return Curl_ip2addr(AF_INET, &in, hostname, port);
-
+ {
+ struct in_addr in;
+ /* First check if this is an IPv4 address string */
+ if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
+ /* This is a dotted IP address 123.123.123.123-style */
+ return Curl_ip2addr(AF_INET, &in, hostname, port);
+ }
#ifdef CURLRES_IPV6
- /* check if this is an IPv6 address string */
- if(Curl_inet_pton(AF_INET6, hostname, &in6) > 0)
- /* This is an IPv6 address literal */
- return Curl_ip2addr(AF_INET6, &in6, hostname, port);
+ {
+ struct in6_addr in6;
+ /* check if this is an IPv6 address string */
+ if(Curl_inet_pton(AF_INET6, hostname, &in6) > 0)
+ /* This is an IPv6 address literal */
+ return Curl_ip2addr(AF_INET6, &in6, hostname, port);
+ }
#endif /* CURLRES_IPV6 */
#endif /* !USE_RESOLVE_ON_IPS */
/* fall-back to blocking version */
infof(conn->data, "init_resolve_thread() failed for %s; %s\n",
- hostname, Curl_strerror(conn, ERRNO));
+ hostname, Curl_strerror(conn, errno));
error = Curl_getaddrinfo_ex(hostname, sbuf, &hints, &res);
if(error) {