int SocketSet::private_select( timeval* timeout ) { #ifdef VSNET_DEBUG timeval* enter_timeout = NULL; if( timeout ) enter_timeout = new timeval(*timeout); fd_set debug_copy_of_read_set_select; fd_set debug_copy_of_write_set_select; FD_ZERO( &debug_copy_of_read_set_select ); FD_ZERO( &debug_copy_of_write_set_select ); #endif fd_set read_set_select; fd_set write_set_select; int max_sock_select = 0; FD_ZERO( &read_set_select ); FD_ZERO( &write_set_select ); if( !_client_mgr.expired() ) { boost::shared_ptr<VsnetDownload::Client::Manager> mgr( _client_mgr.lock()); if( (bool)mgr ) { mgr->lower_check_queues( ); } } if( !_server_mgr.expired() ) { boost::shared_ptr<VsnetDownload::Server::Manager> mgr( _server_mgr.lock() ); if( (bool)mgr ) { mgr->lower_check_queues( ); } } // private_test_dump_request_sets( timeout ); for( Set::iterator it = _autoset.begin(); it != _autoset.end(); it++ ) { VsnetSocketBase* b = (*it); int fd = b->get_fd(); bool wrote_on_negative=false; if (fd<0&&b->write_on_negative()) { b->lower_clean_sendbuf( ); wrote_on_negative=true; fd = b->get_fd(); } if( fd >= 0 ) { private_addset( fd, read_set_select, max_sock_select ); if( b->need_test_writable( )&& !wrote_on_negative ) { private_addset( b->get_write_fd(), write_set_select, max_sock_select ); // printf("Checking for read/writability..."); } else { // printf("Checking for readability..."); } } } #ifndef USE_NO_THREAD private_addset( _thread_wakeup.getread(), read_set_select, max_sock_select ); #endif #ifdef VSNET_DEBUG timeval* used_timeout = NULL; if( timeout ) used_timeout = new timeval(*timeout); for( int i=0; i<max_sock_select; i++ ) { if( FD_ISSET( i, &read_set_select ) ) FD_SET( i, &debug_copy_of_read_set_select ); if( FD_ISSET( i, &write_set_select ) ) FD_SET( i, &debug_copy_of_write_set_select ); } #endif int ret = ::select( max_sock_select, &read_set_select, &write_set_select, 0, timeout ); if( ret == -1 ) { #if defined(_WIN32) && !defined(__CYGWIN__) if( WSAGetLastError()!=WSAEINVAL) COUT<<"WIN32 error : "<<WSAGetLastError()<<endl; #else perror( "Select failed : "); #endif } else if( ret == 0 ) { // printf("Nothing to do.\n"); #ifdef VSNET_DEBUG #if 0 std::ostringstream s1; std::ostringstream s2; if( enter_timeout ) s1 << *enter_timeout << ends; else s1 << "(NULL)" << ends; if( used_timeout ) s2 << *used_timeout << ends; else s2 << "(NULL)" << ends; COUT << "Timeout:" << endl << " *** SocketSet::select called with " << s1.str() << endl << " *** ::select called with " << s2.str() << endl; #endif #endif } else { ret++; #if defined(VSNET_DEBUG) private_test_dump_active_sets( max_sock_select, debug_copy_of_read_set_select, read_set_select, debug_copy_of_write_set_select, write_set_select ); #endif for( Set::iterator it = _autoset.begin(); it != _autoset.end(); it++ ) { VsnetSocketBase* b = (*it); int fd = b->get_fd(); if( fd >= 0 ) { if( FD_ISSET(fd,&read_set_select) ) { // printf("Reading.\n"); if (!b->lower_selected( )) ret--; // No complete packet received yet. } if(b->isReadyToSend(&write_set_select) ) { // printf("Writing.\n"); ret--; b->lower_sendbuf( ); } } else { if(b->isReadyToSend(&write_set_select)) { // printf("reconnecting?\n"); #ifdef VSNET_DEBUG COUT << "saw activity on " << b->get_write_fd() << " but main file descriptor is " << b->get_fd() << endl; #endif b->lower_clean_sendbuf( ); } } } #ifndef USE_NO_THREAD if( FD_ISSET( _thread_wakeup.getread(), &read_set_select ) ) { char c; _thread_wakeup.read( &c, 1 ); } #endif } if( _blockmain ) { // whatever the reason for leaving select, if we have been asked // to signal the main thread on wakeup, we do it _blockmain_mx.lock( ); _blockmain_cond.signal( ); _blockmain_mx.unlock( ); } return ret; }