/* * 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; /* 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). */ *stderr = *td->stderr_file; WSASetLastError (conn->async.status = NO_DATA); /* pending status */ he = gethostbyname (conn->async.hostname); if (he) { Curl_addrinfo4_callback(conn, CURL_ASYNC_SUCCESS, he); rc = 1; } else { Curl_addrinfo4_callback(conn, (int)WSAGetLastError(), NULL); rc = 0; } TRACE(("Winsock-error %d, addr %s\n", conn->async.status, he ? inet_ntoa(*(struct in_addr*)he->h_addr) : "unknown")); 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 handle. * This allows us to use it even after the container gets destroyed * due to a resolver timeout. */ HANDLE mutex_waiting = NULL; HANDLE curr_proc = GetCurrentProcess(); if (!DuplicateHandle(curr_proc, td->mutex_waiting, curr_proc, &mutex_waiting, 0, FALSE, DUPLICATE_SAME_ACCESS)) { /* failed to duplicate the mutex, no point in continuing */ 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 */ he = gethostbyname (conn->async.hostname); /* is the thread initiator still waiting for us ? */ if (WaitForSingleObject(mutex_waiting, 0) == WAIT_TIMEOUT) { /* yes, it is */ /* 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")); } /* clean up */ CloseHandle(mutex_waiting); 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); } release_thread_sync(&tsd); } /* clean up */ destroy_thread_sync_data(&tsd); return (rc); /* An implicit _endthreadex() here */ }