package org.maachang.comet.net ;

import java.util.ArrayList;
import java.util.List;

import org.maachang.comet.httpd.HttpConnectionInfo;
import org.maachang.comet.httpd.HttpSocket;

/**
 * KeepAlive監視用スレッド.
 * 
 * @version 2007/11/17
 * @author  masahito suzuki
 * @since   MaachangComet 1.00
 */
class KeepAliveTimeoutThread extends Thread {
    
    private List<HttpConnectionInfo> manager = null ;
    private volatile boolean stopFlag = false ;
    private final Object sync = new Object() ;
    
    public KeepAliveTimeoutThread() {
        this.manager = new ArrayList<HttpConnectionInfo>() ;
        this.stopFlag = false ;
        this.setDaemon( true ) ;
        this.start() ;
    }
    
    public void destroy() {
        setStop( true ) ;
        synchronized( sync ) {
            if( manager != null ) {
                manager.clear() ;
            }
            manager = null ;
        }
    }
    
    public void append( HttpConnectionInfo conn ) {
        if( conn == null || conn.isUse() == false ) {
            return ;
        }
        synchronized( sync ) {
            this.manager.add( conn ) ;
        }
    }
    
    public void remove( HttpConnectionInfo conn ) {
        if( conn == null || conn.isUse() == false ) {
            return ;
        }
        synchronized( sync ) {
            int len = this.manager.size() ;
            for( int i = 0 ; i < len ; i ++ ) {
                if( this.manager.get( i ) == conn ) {
                    this.manager.set( i,null ) ;
                }
            }
        }
    }
    
    public synchronized boolean isStop() {
        return stopFlag ;
    }
    
    private synchronized void setStop( boolean mode ) {
        this.stopFlag = mode ;
    }
    
    private static final long WAIT_TIME = 500 ;
    
    public void run() {
        ThreadDeath threadDeach = null ;
        boolean endFlag = false ;
        for( ;; ) {
            try {
                Thread.sleep( WAIT_TIME ) ;
                synchronized( sync ) {
                    if( endFlag == true || isStop() == true || manager == null ) {
                        endFlag = true ;
                        break ;
                    }
                }
                int len = 0 ;
                synchronized( sync ) {
                    len = manager.size() ;
                }
                if( len > 0 ) {
                    for( int i = len-1 ; i >= 0 ; i -- ) {
                        HttpConnectionInfo conn = null ;
                        synchronized( sync ) {
                            conn = manager.get( i ) ;
                        }
                        if( conn == null || conn.isUse() == false ) {
                            synchronized( sync ) {
                                manager.remove( i ) ;
                            }
                            continue ;
                        }
                        if( conn.getTimer() + conn.getTimeout() <= System.currentTimeMillis() ) {
                            HttpSocket socket = conn.getSocket() ;
                            socket.destroy() ;
                            synchronized( sync ) {
                                manager.remove( i ) ;
                            }
                        }
                    }
                }
            } catch( InterruptedException ie ) {
                endFlag = true ;
            } catch ( NullPointerException ne ) {
            } catch( OutOfMemoryError mem ) {
            } catch( Exception e ) {
            } catch( ThreadDeath td ) {
                endFlag = true ;
                threadDeach = td ;
            }
        }
        setStop( true ) ;
        if( threadDeach != null ) {
            throw threadDeach ;
        }
    }
    
}
