package com.tivoli.jmx.tutorial.managedserver;

import java.util.Iterator;
import java.util.HashSet;

public class HandlerPool implements HandlerPoolMBean {
  private java.util.Set handlers;
  private int size;
  private int epoch = 0;

  public HandlerPool() {
    this.handlers = new HashSet();
    this.size = 8;
    fill();
  }

  public HandlerPool(int size) {
    this.size = size;
    fill();
  }

  private void fill() {
    for (int i = 0; i < this.size; i++) {
      Handler h = new Handler(this, epoch);
      h.start();
      handlers.add(h);
    }
  }

  public int getSize() {
    return size;
  }

  public void refill() {
    synchronized (handlers) {
      epoch++;
      fill();
    }
  }

  public void release(Handler handler) {
    synchronized (handlers) {
      if (handler.getEpoch() == epoch) {
        handlers.add(handler);
        handlers.notify();
      }
    }
  }

  public Handler reserve() {
    Handler h = null;

    synchronized (handlers) {
      while (handlers.isEmpty()) {
        try { handlers.wait(); } catch (InterruptedException x) {}
      }
      Iterator i = handlers.iterator();
      h = (Handler) i.next();
      handlers.remove(h);
    }

    return h;
  }

  public void setSize(int size) {
    synchronized (handlers) {
      if (this.size > size) throw new IllegalArgumentException("Can't decrease size");
      for (int delta = this.size - size; delta > 0; delta--) {
        handlers.add(new Handler(this));
      }
      this.size = size;
    }
  }
}