package org.maachang.proxy.engine.net.http;

import java.io.IOException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 受信待ち監視スレッド.
 * 
 * @version 2007/11/17
 * @author  masahito suzuki
 * @since MaachangProxy 1.00
 */
class NetReceiveThread extends Thread {
    
    private static final Log LOG = LogFactory.getLog( NetReceiveThread.class ) ;
    private KeepAliveTimerManager timeMan = null ;
    private NetSocketManager manager = null ;
    private NetUseQueue queue = null ;
    private volatile boolean stopFlag = true ;
    
    private NetReceiveThread() {
        
    }
    
    public NetReceiveThread( KeepAliveTimerManager timerManager,NetSocketManager manager )
        throws Exception {
        this.timeMan = timerManager ;
        this.manager = manager ;
        this.queue = new NetUseQueue() ;
        this.stopFlag = false ;
        this.setDaemon( true ) ;
        this.start() ;
    }
    
    public void destroy() {
        setStop( true ) ;
    }
    
    public NetUseQueue getUseQueue() {
        return this.queue ;
    }
    
    public synchronized boolean isStop() {
        return stopFlag ;
    }
    
    private synchronized void setStop( boolean mode ) {
        this.stopFlag = mode ;
    }
    
    public void run() {
        boolean endFlag = false ;
        ThreadDeath threadDeach = null ;
        for( ;; ) {
            if( endFlag == true || isStop() == true ) {
                break ;
            }
            try {
                int len = this.manager.size() ;
                if( len > 0 ) {
                    for( int i = len-1 ; i >= 0 ; i -- ) {
                        HttpSocket s = null ;
                        try {
                            s = manager.get( i ) ;
                            if( s.isClosed() == true ) {
                                manager.remove( i ) ;
                            }
                            else if( s.isReceive() == true ) {
                                manager.remove( i ) ;
                                ConnectionInfo conn = null ;
                                if( ( conn = s.getConnectionInfo() ) == null ) {
                                    conn = new ConnectionInfo( s,manager,timeMan ) ;
                                    s.setConnectionInfo( conn ) ;
                                }
                                else {
                                    timeMan.remove( conn ) ;
                                }
                                queue.append( s ) ;
                            }
                        } catch( IOException io ) {
                            if( s != null ) {
                                s.destroy() ;
                            }
                            manager.remove( i ) ;
                        } catch( InterruptedException ite ) {
                            endFlag = true ;
                        } catch ( NullPointerException ne ) {
                        } catch( OutOfMemoryError mem ) {
                            LOG.error( "## out-of-memory-error",mem ) ;
                        } catch( Exception e ) {
                            LOG.error( "## error",e ) ;
                        } catch( ThreadDeath td ) {
                            endFlag = true ;
                            threadDeach = td ;
                        }
                    }
                }
                Thread.sleep( 5L ) ;
            } catch( InterruptedException ie ) {
                endFlag = true ;
            }
        }
        this.manager = null ;
        this.queue = null ;
        setStop( true ) ;
        if( threadDeach != null ) {
            throw threadDeach ;
        }
    }
    
}

