1 4 package com.tc.net.core; 5 6 import EDU.oswego.cs.dl.util.concurrent.CopyOnWriteArraySet; 7 8 import com.tc.logging.TCLogger; 9 import com.tc.logging.TCLogging; 10 import com.tc.net.TCSocketAddress; 11 import com.tc.net.core.event.TCListenerEvent; 12 import com.tc.net.core.event.TCListenerEventListener; 13 import com.tc.net.protocol.ProtocolAdaptorFactory; 14 import com.tc.util.Assert; 15 import com.tc.util.TCTimeoutException; 16 import com.tc.util.concurrent.SetOnceFlag; 17 import com.tc.util.concurrent.TCExceptionResultException; 18 import com.tc.util.concurrent.TCFuture; 19 20 import java.net.InetAddress ; 21 import java.net.ServerSocket ; 22 import java.util.Iterator ; 23 24 29 abstract class AbstractTCListener implements TCListener { 30 protected final static TCLogger logger = TCLogging.getLogger(TCListener.class); 31 32 private final InetAddress addr; 33 private final int port; 34 private final TCSocketAddress sockAddr; 35 36 private final TCListenerEvent staticEvent; 37 38 private final SetOnceFlag closeEventFired = new SetOnceFlag(); 39 private final SetOnceFlag stopPending = new SetOnceFlag(); 40 private final SetOnceFlag stopped = new SetOnceFlag(); 41 42 private final CopyOnWriteArraySet listeners = new CopyOnWriteArraySet(); 43 44 private final ProtocolAdaptorFactory factory; 45 46 AbstractTCListener(ServerSocket ss, ProtocolAdaptorFactory factory) { 47 this.addr = ss.getInetAddress(); 48 this.port = ss.getLocalPort(); 49 this.sockAddr = new TCSocketAddress(this.addr, this.port); 50 this.factory = factory; 51 this.staticEvent = new TCListenerEvent() { 52 public TCListener getSource() { 53 return AbstractTCListener.this; 54 } 55 }; 56 } 57 58 abstract protected void stopImpl(Runnable callback); 59 60 public final void stop() { 61 try { 62 stop(0); 63 } catch (Exception e) { 64 logger.error("unexpected exception", e); 65 } 66 } 67 68 public final TCSocketAddress getBindSocketAddress() { 69 return sockAddr; 70 } 71 72 public final void stop(long timeout) throws TCTimeoutException { 73 if (stopped.isSet()) { 74 logger.warn("listener already stopped"); 75 return; 76 } 77 78 if (stopPending.attemptSet()) { 79 final TCFuture future = new TCFuture(); 80 81 stopImpl(new Runnable () { 82 public void run() { 83 future.set("stop done"); 84 } 85 }); 86 87 try { 88 future.get(timeout); 89 } catch (InterruptedException e) { 90 logger.warn("stop interrupted"); 91 return; 92 } catch (TCExceptionResultException e) { 93 logger.error(e); 94 Assert.eval("exception result set in future", false); 95 return; 96 } finally { 97 fireCloseEvent(); 98 stopped.set(); 99 } 100 } else { 101 logger.warn("stop already requested"); 102 } 103 } 104 105 public final int getBindPort() { 106 return port; 107 } 108 109 public final InetAddress getBindAddress() { 110 return addr; 111 } 112 113 public final void addEventListener(TCListenerEventListener lsnr) { 114 if (lsnr == null) { 115 logger.warn("trying to add a null event listener"); 116 return; 117 } 118 119 listeners.add(lsnr); 120 } 121 122 public final void removeEventListener(TCListenerEventListener lsnr) { 123 if (lsnr == null) { 124 logger.warn("trying to remove a null event listener"); 125 return; 126 } 127 128 listeners.remove(lsnr); 129 } 130 131 public final boolean isStopped() { 132 return stopped.isSet(); 133 } 134 135 public final String toString() { 136 return getClass().getName() + " " + addr.getHostAddress() + ":" + port; 137 } 138 139 protected final void fireCloseEvent() { 140 if (closeEventFired.attemptSet()) { 141 for (final Iterator iter = listeners.iterator(); iter.hasNext();) { 142 final TCListenerEventListener lsnr = (TCListenerEventListener) iter.next(); 143 144 try { 145 lsnr.closeEvent(staticEvent); 146 } catch (Exception e) { 147 logger.error("exception in close event handler", e); 148 } 149 } 150 } 151 } 152 153 final ProtocolAdaptorFactory getProtocolAdaptorFactory() { 154 return factory; 155 } 156 } | Popular Tags |