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;
}