title: C++/Win. Not getting FD_CLOSE
body: <p>I have an asynchronous socket and call to connect() + GetLastError() which returns WSA_WOULD_BLOCK, as expected. So I start "receiving/reading" thread and subscribe Event to FD_READ and FD_CLOSE.</p>
  
  <p>The story is: connect will sequentially fail, since Server is not up and running. My understanding that my receiving thread should get FD_CLOSE soon and I need to follow-up with cleaning.</p>
  
  <p>It does not happen. How soon should I receive FD_CLOSE? Is it proper approach? Is there any other way to understand that connect() failed? Shoul I ever receive FD_CLOSE if socket isn't connected?</p>
  
  <p>I do start my receiving thread and subscribe event after successful call to DoConnect() and I am afraid that racing condition prevents me from getting FD_CLOSE.</p>
  
  <p>Here is some code:</p>
  
  <pre><code>int RecvSocketThread::WaitForData()
  {
       int retVal = 0
       while (!retVal)
       {
           // sockets to pool can be added on other threads.
           // please validate that all of them in the pool are connected
           // before doing any reading on them
           retVal = DoWaitForData();
       }
  }
  
  int RecvSocketThread::DoWaitForData()
  {
      // before waiting for incoming data, check if all sockets are connected
      WaitForPendingConnection_DoForAllSocketsInThePool();
  
  
      // other routine to read (FD_READ) or react to FD_CLOSE
      // create array of event (each per socket) and wait
  }
  void RecvSocketThread::WaitForPendingConnection_DoForAllSocketsInThePool()
  {
      // create array and set it for events associated with pending connect sockets
      HANDLE* EventArray = NULL;
      int counter = 0;
      EventArray = new HANDLE[m_RecvSocketInfoPool.size()];
  
      // add those event whose associated socket is still not connected
      // and wait for FD_WRITE and FD_CLOSE. At the end of this function
      // don't forget to switch them to FD_READ and FD_CLOSE
      while (it != m_RecvSocketInfoPool.end())
      {
           RecvSocketInfo* recvSocketInfo = it-&gt;second;
           if (!IsEventSet(recvSocketInfo-&gt;m_Connected, &amp;retVal2))
           {
               ::WSAEventSelect(recvSocketInfo-&gt;m_WorkerSocket, recvSocketInfo-&gt;m_Event, FD_WRITE | FD_CLOSE);
               EventArray[counter++] = recvSocketInfo-&gt;m_Event;
           }
           ++it;
      }
      if (counter)
      {
          DWORD indexSignaled = WaitForMultipleObjects(counter, EventArray, WaitAtLeastOneEvent, INFINITE);
  
          // no matter what is further Wait doen't return for failed to connect socket
  
          if (WAIT_OBJECT_0 &lt;= indexSignaled &amp;&amp;
                     indexSignaled &lt; (WAIT_OBJECT_0 + counter))
          {
              it = m_RecvSocketInfoPool.begin();
              while (it != m_RecvSocketInfoPool.end())
              {
                  RecvSocketInfo* recvSocketInfo = it-&gt;second;
                  if (IsEventSet(recvSocketInfo-&gt;m_Event, NULL))
                  {
                    rc = WSAEnumNetworkEvents(recvSocketInfo-&gt;m_WorkerSocket,
                    recvSocketInfo-&gt;m_Event, &amp;networkEvents);
  
                     // Check recvSocketInfo-&gt;m_Event using WSAEnumnetworkevents
                     // for FD_CLOSE using FD_CLOSE_BIT
                     if ((networkEvents.lNetworkEvents &amp; FD_CLOSE))
                     {
                         recvSocketInfo-&gt;m_FD_CLOSE_Recieved = 1;
                         *retVal = networkEvents.iErrorCode[FD_CLOSE_BIT];
                     }
                     if ((networkEvents.lNetworkEvents &amp; FD_WRITE))
                     {
                         WSASetEvent(recvSocketInfo-&gt;m_Connected);
                         *retVal = networkEvents.iErrorCode[FD_WRITE_BIT];
                     }
                  }
                  ++it;
              }
          }
  
          // if error - DoClean, if FD_WRITE (socket is writable) check if m_Connected
          // before do any sending
      }
  }
  </code></pre>