+
+ private HubManager gethm() {
+ if(hm == null) {
+ hm = new HubManager(this);
+ }
+ return(hm);
+ }
+
+ public synchronized void addHubListener(HubListener hl, boolean addexisting) {
+ gethm().addls(hl, addexisting);
+ }
+
+ public synchronized void removeHubListener(HubListener hl) {
+ gethm().rmls(hl);
+ }
+
+ public synchronized Collection<Hub> getHubs() throws InterruptedException {
+ return(gethm().gethubs());
+ }
+
+ public void close() {
+ conn.close();
+ state = "closed";
+ }
+
+ protected void finalize() {
+ if(state != "closed")
+ close();
+ dispatcher.interrupt();
+ }
+
+ void dispatch(Runnable ev) {
+ dispatcher.dispatch(ev);
+ }
+
+ private static class Dispatcher extends Thread {
+ private Queue<Runnable> q = new LinkedList<Runnable>();
+
+ private Dispatcher() {
+ setDaemon(true);
+ }
+
+ public void dispatch(Runnable ev) {
+ synchronized(q) {
+ q.offer(ev);
+ q.notifyAll();
+ }
+ }
+
+ public void run() {
+ while(true) {
+ try {
+ Runnable r;
+ synchronized(q) {
+ while((r = q.poll()) == null)
+ q.wait();
+ }
+ r.run();
+ } catch(Throwable t) {
+ t.printStackTrace();
+ }
+ }
+ }
+ }