/* JFox, the OpenSource J2EE Application Server
 *
 * Distributable under GNU LGPL license by gun.org
 * more details please visit http://www.huihoo.org/jfox
 */

package org.jfox.pool.thread;

import org.jfox.pool.ObjectPool;


/**
 * @author <a href="mailto:young_yy@hotmail.com">Young Yang</a>
 */

public class PoolableThreadImpl extends Thread implements PoolableThread {
    private boolean available = false;
    private ThreadTask task = null;
    private volatile boolean running = false;
    private static volatile long threadId = 0L;
    private volatile boolean waiting = false;

    public PoolableThreadImpl() {
        super("PoolableThread: " + threadId++);
        start();
        while(!waiting) { // 为了防止该先程还没有启动完毕就返回，造成死锁
            synchronized(this) {
                try {
                    this.wait(1L);
                }
                catch(InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void run() {
        running = true;
        do {
            if(!running) break;
            try {
                synchronized(this) {
                    waiting = true;
                    wait();
                }
            }
            catch(InterruptedException e) {
                e.printStackTrace();
                waiting = false;
                if(!running || task == null) break;
            }

            waiting = false; // have wakeup
            if(task == null) break; // maybe wakeup by discard() method
            try {
                task.getTask().run();
            }
            catch(Exception e) {
            }
            finally {
                // must restore the WorkThread to object pool
                synchronized(this) {
                    ObjectPool pool = task.getPool();
                    synchronized(pool) {
                        pool.restoreObject(this);
                    }
                }
            }

        } while(true);
    }

    public void activate() throws Exception {
//    System.out.println("PoolableThreadImpl.activate");
        available = true;
        running = true;

    }

    public void passivate() throws Exception {
//    System.out.println("PoolableThreadImpl.passivate");
        available = false;
        task = null;
    }

    public boolean isAvailable() {
        return available;
    }

    public void setTask(ThreadTask task) {
//    System.out.println("PoolableThreadImpl.setTask" + getName() + " waiting " + waiting + ", running " + running );
        if(waiting == true) {
            this.task = task;
            synchronized(this) {
                notify();
            }
        }
    }

    public void discard() {
        running = false;
        synchronized(this) {
            notifyAll();
        }
        task.getPool().removeObject(this);
    }

    // thread will not sleep , so will not timeout
    public long getSleepTime() {
        return 0;
    }

}