--- ..\..\curl\curl-7.12.1\lib\hostthre.c	2004-06-26 12:58:56.000000000 +0200
+++ hostthre.c	2004-10-15 16:42:12.087744000 +0200
@@ -156,6 +156,8 @@
   DWORD  thread_status;
   curl_socket_t dummy_sock;   /* dummy for Curl_fdset() */
   FILE *stderr_file;
+  HANDLE mutex_waiting;  /* marks that we are still waiting for a resolve */
+  HANDLE event_resolved; /* marks that the thread obtained the information */
 #ifdef CURLRES_IPV6
   struct addrinfo hints;
 #endif
@@ -176,6 +178,16 @@
   struct hostent *he;
   int    rc;
 
+  /* 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;
+  if( FALSE == DuplicateHandle( GetCurrentProcess(), td->mutex_waiting, GetCurrentProcess(), &mutex_waiting, 0, FALSE, DUPLICATE_SAME_ACCESS ) ) {
+	  /* failed to duplicate the mutex, no point in continuing */
+	  return 0;
+  }
+
   /* 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).
@@ -184,16 +196,32 @@
 
   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;
+
+  /* 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) {
+        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"));
   }
-  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 */
 }
@@ -215,6 +243,16 @@
   char   service [NI_MAXSERV];
   int    rc;
 
+  /* 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;
+  if( FALSE == DuplicateHandle( GetCurrentProcess(), td->mutex_waiting, GetCurrentProcess(), &mutex_waiting, 0, FALSE, DUPLICATE_SAME_ACCESS ) ) {
+	  /* failed to duplicate the mutex, no point in continuing */
+	  return 0;
+  }
+
   *stderr = *td->stderr_file;
 
   itoa(conn->async.port, service, 10);
@@ -223,16 +261,32 @@
 
   rc = getaddrinfo(conn->async.hostname, service, &td->hints, &res);
 
-  if (rc == 0) {
-#ifdef DEBUG_THREADING_GETADDRINFO
-    dump_addrinfo (conn, res);
-#endif
-    Curl_addrinfo6_callback(conn, CURL_ASYNC_SUCCESS, res);
-  }
-  else {
-    Curl_addrinfo6_callback(conn, (int)WSAGetLastError(), NULL);
-    TRACE(("Winsock-error %d, no address\n", conn->async.status));
+  /* 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 (rc == 0) {
+    #ifdef DEBUG_THREADING_GETADDRINFO
+        dump_addrinfo (conn, res);
+    #endif
+        Curl_addrinfo6_callback(conn, CURL_ASYNC_SUCCESS, res);
+    }
+    else {
+        Curl_addrinfo6_callback(conn, (int)WSAGetLastError(), NULL);
+        TRACE(("Winsock-error %d, no address\n", conn->async.status));
+    }
   }
+
+  /* clean up */
+  CloseHandle( mutex_waiting );
+
   return (rc);
   /* An implicit _endthreadex() here */
 }
@@ -244,6 +298,8 @@
  */
 static void destroy_thread_data (struct Curl_async *async)
 {
+  struct thread_data *td;
+
   if (async->hostname)
     free(async->hostname);
 
@@ -252,6 +308,14 @@
 
     if (sock != CURL_SOCKET_BAD)
       sclose(sock);
+
+    /* destroy the synchronization objects */
+    td = (struct thread_data*) async->os_specific;
+    if( td->mutex_waiting )
+        CloseHandle( td->mutex_waiting );
+    if( td->event_resolved )
+        CloseHandle( td->event_resolved );
+
     free(async->os_specific);
   }
   async->hostname = NULL;
@@ -289,6 +353,18 @@
   conn->async.dns = NULL;
   conn->async.os_specific = (void*) td;
 
+  /* Create the mutex used to inform the resolver thread that we're
+   * still waiting, and take initial ownership.
+   */
+  td->mutex_waiting = CreateMutex( NULL, TRUE, NULL );
+  if( td->mutex_waiting == NULL ) return FALSE;
+
+  /* Create the event that the thread uses to inform us that it's
+   * done resolving. Do not signal it.
+   */
+  td->event_resolved = CreateEvent( NULL, TRUE, FALSE, NULL );
+  if( td->event_resolved == NULL ) return FALSE;
+
   td->dummy_sock = CURL_SOCKET_BAD;
   td->stderr_file = stderr;
   td->thread_hnd = (HANDLE) _beginthreadex(NULL, 0, THREAD_FUNC,
@@ -342,8 +418,25 @@
     CURL_TIMEOUT_RESOLVE; /* default name resolve timeout */
   ticks = GetTickCount();
 
-  status = WaitForSingleObject(td->thread_hnd, 1000UL*timeout);
-  if (status == WAIT_OBJECT_0 || status == WAIT_ABANDONED) {
+  /* wait for the thread to resolve the name */
+  status = WaitForSingleObject( td->event_resolved, 1000UL*timeout );
+
+  /* mark that we are now done waiting */
+  ReleaseMutex( td->mutex_waiting );
+  /* close our handle to the mutex, no point in hanging on to it */
+  CloseHandle( td->mutex_waiting );
+  td->mutex_waiting = NULL;
+
+  /* close the event handle, it's useless now */
+  CloseHandle( td->event_resolved );
+  td->event_resolved = NULL;
+
+  /* has the resolver thread succeeded in resolving our query ? */
+  if( status == WAIT_OBJECT_0 )
+  {
+    /* wait for the thread to exit, it's in the callback sequence */
+    WaitForSingleObject( td->thread_hnd, INFINITE );
+
      /* Thread finished before timeout; propagate Winsock error to this thread.
       * 'conn->async.done = TRUE' is set in Curl_addrinfo4/6_callback().
       */
