ConnectionPtr SocketConnection::acceptSync() { LB_TS_THREAD( _recvThread ); if( !isListening( )) return 0; LBASSERT( _overlappedAcceptData ); LBASSERT( _overlappedSocket != INVALID_SOCKET ); if( _overlappedSocket == INVALID_SOCKET ) return 0; // complete accept DWORD got = 0; DWORD flags = 0; if( !WSAGetOverlappedResult( _readFD, &_overlappedRead, &got, TRUE, &flags )) { LBWARN << "Accept completion failed: " << lunchbox::sysError << ", closing socket" << std::endl; close(); return 0; } sockaddr_in* local = 0; sockaddr_in* remote = 0; int localLen = 0; int remoteLen = 0; GetAcceptExSockaddrs( _overlappedAcceptData, 0, sizeof( sockaddr_in ) + 16, sizeof( sockaddr_in ) + 16, (sockaddr**)&local, &localLen, (sockaddr**)&remote, &remoteLen ); _tuneSocket( _overlappedSocket ); ConstConnectionDescriptionPtr description = getDescription(); SocketConnection* newConnection = new SocketConnection; ConnectionPtr connection( newConnection ); // to keep ref-counting correct newConnection->_readFD = _overlappedSocket; newConnection->_writeFD = _overlappedSocket; #ifndef _WIN32 //fcntl( _overlappedSocket, F_SETFL, O_NONBLOCK ); #endif newConnection->_initAIORead(); _overlappedSocket = INVALID_SOCKET; newConnection->_setState( STATE_CONNECTED ); ConnectionDescriptionPtr newDescription = newConnection->_getDescription(); newDescription->bandwidth = description->bandwidth; newDescription->port = ntohs( remote->sin_port ); newDescription->setHostname( getHostName( *remote )); LBDEBUG << "accepted connection from " << newDescription->getHostname() << ":" << newDescription->port << std::endl; return connection; }
ConnectionPtr SocketConnection::acceptSync() { if( !isListening( )) return 0; sockaddr_in newAddress; socklen_t newAddressLen = sizeof( newAddress ); Socket fd; unsigned nTries = 1000; do fd = ::accept( _readFD, (sockaddr*)&newAddress, &newAddressLen ); while( fd == INVALID_SOCKET && errno == EINTR && --nTries ); if( fd == INVALID_SOCKET ) { LBWARN << "accept failed: " << lunchbox::sysError << std::endl; return 0; } _tuneSocket( fd ); ConstConnectionDescriptionPtr description = getDescription(); SocketConnection* newConnection = new SocketConnection; newConnection->_readFD = fd; newConnection->_writeFD = fd; newConnection->_setState( STATE_CONNECTED ); ConnectionDescriptionPtr newDescription = newConnection->_getDescription(); newDescription->bandwidth = description->bandwidth; newDescription->port = ntohs( newAddress.sin_port ); newDescription->setHostname( inet_ntoa( newAddress.sin_addr )); LBDEBUG << "Accepted " << newDescription->toString() << std::endl; return newConnection; }