package org.maachang.rawio.async ;


/**
 * 非同期書込みスレッド.
 * 
 * @version 2008/06/12
 * @author  masahito suzuki
 * @since   Rawio 1.00
 */
class ASyncWriteThread extends AbstractLoopThread {
    
    /**
     * キューオブジェクト.
     */
    private ASyncQueue queue = null ;
    
    /**
     * コンストラクタ.
     */
    private ASyncWriteThread() {
        
    }
    
    /**
     * コンストラクタ.
     * @param queue 対象のキューを設定します.
     * @exception Exception 例外.
     */
    public ASyncWriteThread( ASyncQueue queue )
        throws Exception {
        this.queue = queue ;
        this.startThread() ;
    }
    
    /**
     * デストラクタ.
     */
    protected void finalize() throws Exception {
        this.destroy() ;
    }
    
    /**
     * オブジェクト破棄.
     */
    public void destroy() {
        super.stopThread() ;
    }
    
    /**
     * オブジェクトクリア処理.
     * <p>スレッドが停止したときに呼び出されます.</p>
     */
    protected void clear() {
        this.queue = null ;
    }
    
    /**
     * 実行処理.
     * <p>スレッド実行を行う実装を行います.</p>
     * @return boolean [false]の場合、Thread.sleep(30)が発生します.
     * @exception Exception 例外.
     */
    protected boolean execution() throws Exception {
        boolean writeFlag = false ;
        ASyncElement element = queue.getQueue() ;
        if( element == null ) {
            Thread.sleep( 1L ) ;
            return true ;
        }
        int no = -1 ;
        ASyncWriteLock lock = null ;
        try {
            lock = element.getLock() ;
            no = element.getNo() ;
            if( lock != null && lock.flag( no ) ) {
                writeFlag = true ;
                try {
                    element.getRaw().write( element.getData(),no ) ;
                } finally {
                    lock.off( no ) ;
                }
            }
            return true ;
        } catch( Exception e ) {
            if( lock != null && lock.flag( no ) ) {
                writeFlag = true ;
            }
            throw e ;
        } finally {
            if( writeFlag == true ) {
                try {
                    queue.relaseElement() ;
                } catch( Exception e ) {
                }
            }
        }
    }
    
}
