/* JFox, the OpenSource J2EE Application Server
 *
 * Copyright (C) 2002 huihoo.org
 * Distributable under GNU LGPL license
 * See the GNU Lesser General Public License for more details.
 */

package org.huihoo.jfox.pool.thread;

import org.huihoo.jfox.pool.ObjectPool;


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

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

  public WorkerThread() {
    super("WorkerThread: " + threadId++);
//    System.out.println("make WorkerThread: " + (threadId -1));
    running = true;
    this.start();
  }

  public void run() {
    do {
      if(!running) break;
      try{
//        System.out.println("WorkerThread.run " + this.getName() + ", waiting " + waiting);
        synchronized(this){
          waiting = true;
//          System.out.println("WorkerThread.run " + this.getName() + ", waiting " + waiting);
          wait();
//          System.out.println("WorkerThread.run " + this.getName() + " have wakenup");
        }
      }
      catch(InterruptedException e){
        e.printStackTrace();
        waiting = false;
        if(!running || task == null) break;
      }

//      System.out.println("WorkerThread.wakeup " + this.getName());

      waiting = false; // have wakeup
      if(task == null) break; // maybe wakeup by discard() method
      try {
        task.getTask().run();
      }
      catch(Throwable throwable) {
//        System.err.println("WorkerThread:Ignored Exception: " + throwable.toString());
      }
      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("WorkerThread.activate");
    running = true;
  }

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

  public void destory() throws Exception {
    notifyAll();
  }

  public void setTask(ThreadTask task){
//    System.out.println("WorkerThread.setTask" + getName() + " waiting " + waiting + ", running " + running );
    if(waiting == true) {
      this.task = task;
      synchronized(this) {
        System.out.println("WorkerThread.setTask.notifyAll " + getName());
        try {
          sleep(10L);
        }
        catch(InterruptedException e){
          e.printStackTrace();
        }
        notifyAll();
      }
    }
  }

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

}
