summaryrefslogtreecommitdiff
path: root/libs/libcurl/src/asyn-thread.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/libcurl/src/asyn-thread.c')
-rw-r--r--libs/libcurl/src/asyn-thread.c63
1 files changed, 48 insertions, 15 deletions
diff --git a/libs/libcurl/src/asyn-thread.c b/libs/libcurl/src/asyn-thread.c
index 779f285283..d6687fe8f8 100644
--- a/libs/libcurl/src/asyn-thread.c
+++ b/libs/libcurl/src/asyn-thread.c
@@ -168,7 +168,7 @@ struct thread_sync_data {
duplicate */
#ifndef CURL_DISABLE_SOCKETPAIR
struct Curl_easy *data;
- curl_socket_t sock_pair[2]; /* socket pair */
+ curl_socket_t sock_pair[2]; /* eventfd/pipes/socket pair */
#endif
int sock_error;
struct Curl_addrinfo *res;
@@ -251,7 +251,7 @@ int init_thread_sync_data(struct thread_data *td,
#ifndef CURL_DISABLE_SOCKETPAIR
/* create socket pair or pipe */
- if(wakeup_create(&tsd->sock_pair[0]) < 0) {
+ if(wakeup_create(tsd->sock_pair, FALSE) < 0) {
tsd->sock_pair[0] = CURL_SOCKET_BAD;
tsd->sock_pair[1] = CURL_SOCKET_BAD;
goto err_exit;
@@ -286,7 +286,7 @@ static CURLcode getaddrinfo_complete(struct Curl_easy *data)
result = Curl_addrinfo_callback(data, tsd->sock_error, tsd->res);
/* The tsd->res structure has been copied to async.dns and perhaps the DNS
- cache. Set our copy to NULL so destroy_thread_sync_data doesn't free it.
+ cache. Set our copy to NULL so destroy_thread_sync_data does not free it.
*/
tsd->res = NULL;
@@ -302,6 +302,14 @@ query_complete(DWORD err, DWORD bytes, LPWSAOVERLAPPED overlapped)
struct Curl_addrinfo *ca;
struct Curl_addrinfo *cafirst = NULL;
struct Curl_addrinfo *calast = NULL;
+#ifndef CURL_DISABLE_SOCKETPAIR
+#ifdef USE_EVENTFD
+ const void *buf;
+ const uint64_t val = 1;
+#else
+ char buf[1];
+#endif
+#endif
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wcast-align"
@@ -421,11 +429,14 @@ query_complete(DWORD err, DWORD bytes, LPWSAOVERLAPPED overlapped)
}
else {
#ifndef CURL_DISABLE_SOCKETPAIR
- char buf[1];
if(tsd->sock_pair[1] != CURL_SOCKET_BAD) {
- /* DNS has been resolved, signal client task */
+#ifdef USE_EVENTFD
+ buf = &val;
+#else
buf[0] = 1;
- if(swrite(tsd->sock_pair[1], buf, sizeof(buf)) < 0) {
+#endif
+ /* DNS has been resolved, signal client task */
+ if(wakeup_write(tsd->sock_pair[1], buf, sizeof(buf)) < 0) {
/* update sock_erro to errno */
tsd->sock_error = SOCKERRNO;
}
@@ -447,15 +458,26 @@ query_complete(DWORD err, DWORD bytes, LPWSAOVERLAPPED overlapped)
* For builds without ARES, but with USE_IPV6, create a resolver thread
* and wait on it.
*/
-static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg)
+static
+#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP)
+DWORD
+#else
+unsigned int
+#endif
+CURL_STDCALL getaddrinfo_thread(void *arg)
{
struct thread_sync_data *tsd = (struct thread_sync_data *)arg;
struct thread_data *td = tsd->td;
char service[12];
int rc;
#ifndef CURL_DISABLE_SOCKETPAIR
+#ifdef USE_EVENTFD
+ const void *buf;
+ const uint64_t val = 1;
+#else
char buf[1];
#endif
+#endif
msnprintf(service, sizeof(service), "%d", tsd->port);
@@ -480,9 +502,13 @@ static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg)
else {
#ifndef CURL_DISABLE_SOCKETPAIR
if(tsd->sock_pair[1] != CURL_SOCKET_BAD) {
- /* DNS has been resolved, signal client task */
+#ifdef USE_EVENTFD
+ buf = &val;
+#else
buf[0] = 1;
- if(wakeup_write(tsd->sock_pair[1], buf, sizeof(buf)) < 0) {
+#endif
+ /* DNS has been resolved, signal client task */
+ if(wakeup_write(tsd->sock_pair[1], buf, sizeof(buf)) < 0) {
/* update sock_erro to errno */
tsd->sock_error = SOCKERRNO;
}
@@ -500,7 +526,13 @@ static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg)
/*
* gethostbyname_thread() resolves a name and then exits.
*/
-static unsigned int CURL_STDCALL gethostbyname_thread(void *arg)
+static
+#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP)
+DWORD
+#else
+unsigned int
+#endif
+CURL_STDCALL gethostbyname_thread(void *arg)
{
struct thread_sync_data *tsd = (struct thread_sync_data *)arg;
struct thread_data *td = tsd->td;
@@ -638,7 +670,8 @@ static bool init_resolve_thread(struct Curl_easy *data,
#ifdef _WIN32
if(Curl_isWindows8OrGreater && Curl_FreeAddrInfoExW &&
- Curl_GetAddrInfoExCancel && Curl_GetAddrInfoExW) {
+ Curl_GetAddrInfoExCancel && Curl_GetAddrInfoExW &&
+ !Curl_win32_impersonating()) {
#define MAX_NAME_LEN 256 /* max domain name is 253 chars */
#define MAX_PORT_LEN 8
WCHAR namebuf[MAX_NAME_LEN];
@@ -664,7 +697,7 @@ static bool init_resolve_thread(struct Curl_easy *data,
NULL, &td->tsd.w8.overlapped,
&query_complete, &td->tsd.w8.cancel_ev);
if(err != WSA_IO_PENDING)
- query_complete(err, 0, &td->tsd.w8.overlapped);
+ query_complete((DWORD)err, 0, &td->tsd.w8.overlapped);
return TRUE;
}
}
@@ -757,8 +790,8 @@ void Curl_resolver_kill(struct Curl_easy *data)
{
struct thread_data *td = data->state.async.tdata;
- /* If we're still resolving, we must wait for the threads to fully clean up,
- unfortunately. Otherwise, we can simply cancel to clean up any resolver
+ /* If we are still resolving, we must wait for the threads to fully clean up,
+ unfortunately. Otherwise, we can simply cancel to clean up any resolver
data. */
#ifdef _WIN32
if(td && td->complete_ev) {
@@ -829,7 +862,7 @@ CURLcode Curl_resolver_is_resolved(struct Curl_easy *data,
}
else {
/* poll for name lookup done with exponential backoff up to 250ms */
- /* should be fine even if this converts to 32 bit */
+ /* should be fine even if this converts to 32-bit */
timediff_t elapsed = Curl_timediff(Curl_now(),
data->progress.t_startsingle);
if(elapsed < 0)