package org.maachang.comet.net ;

import java.io.IOException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.maachang.comet.httpd.HttpConnectionInfo;
import org.maachang.comet.httpd.HttpSocket;

/**
 * 受信待ち監視スレッド.
 * 
 * @version 2007/11/17
 * @author  masahito suzuki
 * @since   MaachangComet 1.00
 */
class NetReceiveThread extends Thread {
    
    private static final Log LOG = LogFactory.getLog( NetReceiveThread.class ) ;
    private KeepAliveTimerManager timeMan = null ;
    private HttpSocketManager manager = null ;
    private HttpUseQueue queue = null ;
    private volatile boolean stopFlag = true ;
    
    private NetReceiveThread() {
        
    }
    
    public NetReceiveThread( KeepAliveTimerManager timerManager,HttpSocketManager manager )
        throws Exception {
        this.timeMan = timerManager ;
        this.manager = manager ;
        this.queue = new HttpUseQueue() ;
        this.stopFlag = false ;
        this.setDaemon( true ) ;
        this.start() ;
    }
    
    public void destroy() {
        setStop( true ) ;
    }
    
    public HttpUseQueue 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 {
                                s.startReceive() ;
                                if( s.isReceive() == true ) {
                                    manager.remove( i ) ;
                                    HttpConnectionInfo conn = null ;
                                    if( ( conn = s.getConnectionInfo() ) == null ) {
                                        conn = new NetHttpConnectionInfoImpl( 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 ;
        }
    }
    
}

