/* * getaddrinfo_thread() resolves a name, calls Curl_addrinfo6_callback and then * exits. * * For builds without ARES, but with ENABLE_IPV6, create a resolver thread * and wait on it. */ static unsigned __stdcall getaddrinfo_thread (void *arg) { struct connectdata *conn = (struct connectdata*) arg; struct thread_data *td = (struct thread_data*) conn->async.os_specific; struct addrinfo *res; char service [NI_MAXSERV]; int rc; struct addrinfo hints = td->hints; /* Duplicate the passed mutex handle. * This allows us to use it even after the container gets destroyed * due to a resolver timeout. */ struct thread_sync_data tsd = { 0,0,0,NULL }; if (!init_thread_sync_data(td, conn->async.hostname, &tsd)) { /* thread synchronization data initialization failed */ return -1; } #ifndef _WIN32_WCE *stderr = *td->stderr_file; #endif itoa(conn->async.port, service, 10); WSASetLastError(conn->async.status = NO_DATA); /* pending status */ /* Signaling that we have initialized all copies of data and handles we need */ SetEvent(td->event_thread_started); rc = getaddrinfo(tsd.hostname, service, &hints, &res); /* is parent thread waiting for us and are we able to access conn members? */ if (acquire_thread_sync(&tsd)) { /* Mark that we have obtained the information, and that we are calling back with it. */ SetEvent(td->event_resolved); if (rc == 0) { #ifdef DEBUG_THREADING_GETADDRINFO dump_addrinfo (conn, res); #endif rc = Curl_addrinfo6_callback(conn, CURL_ASYNC_SUCCESS, res); } else { rc = Curl_addrinfo6_callback(conn, (int)WSAGetLastError(), NULL); TRACE(("Winsock-error %d, no address\n", conn->async.status)); } release_thread_sync(&tsd); } /* clean up */ destroy_thread_sync_data(&tsd); return (rc); /* An implicit _endthreadex() here */ }
/* * getaddrinfo_thread() resolves a name, calls Curl_addrinfo6_callback and then * exits. * * For builds without ARES, but with ENABLE_IPV6, create a resolver thread * and wait on it. */ static unsigned __stdcall getaddrinfo_thread (void *arg) { struct connectdata *conn = (struct connectdata*) arg; struct thread_data *td = (struct thread_data*) conn->async.os_specific; Curl_addrinfo *res; char service [NI_MAXSERV]; int rc; struct addrinfo hints = td->hints; /* Duplicate the passed mutex handle. * This allows us to use it even after the container gets destroyed * due to a resolver timeout. */ struct thread_sync_data tsd = { 0, 0, 0, NULL }; if (!init_thread_sync_data(td, conn->async.hostname, &tsd)) { /* thread synchronization data initialization failed */ return -1; } itoa(conn->async.port, service, 10); conn->async.status = NO_DATA; /* pending status */ SET_SOCKERRNO(conn->async.status); /* Signaling that we have initialized all copies of data and handles we need */ SetEvent(td->event_thread_started); rc = Curl_getaddrinfo_ex(tsd.hostname, service, &hints, &res); /* is parent thread waiting for us and are we able to access conn members? */ if (acquire_thread_sync(&tsd)) { /* Mark that we have obtained the information, and that we are calling back with it. */ SetEvent(td->event_resolved); if (rc == 0) { rc = Curl_addrinfo6_callback(conn, CURL_ASYNC_SUCCESS, res); } else { rc = Curl_addrinfo6_callback(conn, SOCKERRNO, NULL); } release_thread_sync(&tsd); } /* clean up */ destroy_thread_sync_data(&tsd); return (rc); /* An implicit _endthreadex() here */ }
/* * gethostbyname_thread() resolves a name, calls the Curl_addrinfo4_callback * and then exits. * * For builds without ARES/ENABLE_IPV6, create a resolver thread and wait on * it. */ static unsigned __stdcall gethostbyname_thread (void *arg) { struct connectdata *conn = (struct connectdata*) arg; struct thread_data *td = (struct thread_data*) conn->async.os_specific; struct hostent *he; int rc = 0; /* Duplicate the passed mutex and event handles. * This allows us to use it even after the container gets destroyed * due to a resolver timeout. */ struct thread_sync_data tsd = { 0,0,0,NULL }; if (!init_thread_sync_data(td, conn->async.hostname, &tsd)) { /* thread synchronization data initialization failed */ return -1; } /* Sharing the same _iob[] element with our parent thread should * hopefully make printouts synchronised. I'm not sure it works * with a static runtime lib (MSVC's libc.lib). */ #ifndef _WIN32_WCE *stderr = *td->stderr_file; #endif WSASetLastError (conn->async.status = NO_DATA); /* pending status */ /* Signaling that we have initialized all copies of data and handles we need */ SetEvent(td->event_thread_started); he = gethostbyname (tsd.hostname); /* is parent thread waiting for us and are we able to access conn members? */ if (acquire_thread_sync(&tsd)) { /* Mark that we have obtained the information, and that we are calling * back with it. */ SetEvent(td->event_resolved); if (he) { rc = Curl_addrinfo4_callback(conn, CURL_ASYNC_SUCCESS, he); } else { rc = Curl_addrinfo4_callback(conn, (int)WSAGetLastError(), NULL); } TRACE(("Winsock-error %d, addr %s\n", conn->async.status, he ? inet_ntoa(*(struct in_addr*)he->h_addr) : "unknown")); release_thread_sync(&tsd); } /* clean up */ destroy_thread_sync_data(&tsd); return (rc); /* An implicit _endthreadex() here */ }
/* * gethostbyname_thread() resolves a name, calls the Curl_addrinfo4_callback * and then exits. * * For builds without ARES/ENABLE_IPV6, create a resolver thread and wait on * it. */ static unsigned __stdcall gethostbyname_thread (void *arg) { struct connectdata *conn = (struct connectdata*) arg; struct thread_data *td = (struct thread_data*) conn->async.os_specific; struct hostent *he; int rc = 0; /* Duplicate the passed mutex and event handles. * This allows us to use it even after the container gets destroyed * due to a resolver timeout. */ struct thread_sync_data tsd = { 0,0,0,NULL }; if (!init_thread_sync_data(td, conn->async.hostname, &tsd)) { /* thread synchronization data initialization failed */ return (unsigned)-1; } conn->async.status = NO_DATA; /* pending status */ SET_SOCKERRNO(conn->async.status); /* Signaling that we have initialized all copies of data and handles we need */ SetEvent(td->event_thread_started); he = gethostbyname (tsd.hostname); /* is parent thread waiting for us and are we able to access conn members? */ if (acquire_thread_sync(&tsd)) { /* Mark that we have obtained the information, and that we are calling * back with it. */ SetEvent(td->event_resolved); if (he) { rc = Curl_addrinfo4_callback(conn, CURL_ASYNC_SUCCESS, he); } else { rc = Curl_addrinfo4_callback(conn, SOCKERRNO, NULL); } TRACE(("Winsock-error %d, addr %s\n", conn->async.status, he ? inet_ntoa(*(struct in_addr*)he->h_addr) : "unknown")); release_thread_sync(&tsd); } /* clean up */ destroy_thread_sync_data(&tsd); return (rc); /* An implicit _endthreadex() here */ }