1 package org.xsocket.stream.io.impl; 2 3 import java.io.IOException ; 4 import java.nio.channels.ClosedSelectorException ; 5 import java.util.Set ; 6 import java.util.TimerTask ; 7 import java.util.logging.Level ; 8 import java.util.logging.Logger ; 9 10 import org.xsocket.DataConverter; 11 import org.xsocket.Dispatcher; 12 import org.xsocket.IEventHandler; 13 14 15 16 final class IoSocketDispatcher extends Dispatcher<IoSocketHandler> { 17 18 private static final Logger LOG = Logger.getLogger(IoSocketDispatcher.class.getName()); 19 20 static final String DISPATCHER_PREFIX = "xDispatcher"; 21 22 23 private static final long DEFAULT_WATCHDOG_PERIOD_MILLIS = 5L * 60L * 1000L; 25 private long watchDogPeriod = DEFAULT_WATCHDOG_PERIOD_MILLIS; 26 private TimerTask watchDogTask = null; 27 28 private IMemoryManager memoryManager = null; 29 30 private long countIdleTimeouts = 0; 32 private long countConnectionTimeouts = 0; 33 34 35 IoSocketDispatcher(IMemoryManager memoryManager) { 36 super(new DispatcherEventHandler(memoryManager)); 37 38 this.memoryManager = memoryManager; 39 updateTimeoutCheckPeriod(DEFAULT_WATCHDOG_PERIOD_MILLIS); 40 } 41 42 43 @Override 44 public void register(IoSocketHandler handle, int ops) throws IOException { 45 handle.setMemoryManager(memoryManager); 46 super.register(handle, ops); 47 } 48 49 public int getPreallocatedReadMemorySize() { 50 return memoryManager.getFreeBufferSize(); 51 } 52 53 54 void updateTimeoutCheckPeriod(long requiredMinPeriod) { 55 56 if ((watchDogTask != null) && (watchDogPeriod <= requiredMinPeriod)) { 58 return; 59 } 60 61 watchDogPeriod = requiredMinPeriod; 63 if (LOG.isLoggable(Level.FINE)) { 64 LOG.fine("update dispatcher's watchdog task " + DataConverter.toFormatedDuration(watchDogPeriod)); 65 } 66 67 if (watchDogTask != null) { 69 watchDogTask.cancel(); 70 } 71 72 73 watchDogTask = new TimerTask () { 75 @Override 76 public void run() { 77 checkTimeouts(); 78 } 79 }; 80 IoProvider.getTimer().schedule(watchDogTask, watchDogPeriod, watchDogPeriod); 81 } 82 83 84 85 86 @Override 87 public void close() { 88 super.close(); 89 90 if (watchDogTask != null) { 91 watchDogTask.cancel(); 92 } 93 } 94 95 96 long getCountIdleTimeout() { 97 return countIdleTimeouts; 98 } 99 100 long getCountConnectionTimeout() { 101 return countConnectionTimeouts; 102 } 103 104 105 void checkTimeouts() { 106 try { 107 long current = System.currentTimeMillis(); 108 Set <IoSocketHandler> socketHandlers = getRegistered(); 109 for (IoSocketHandler socketHandler : socketHandlers) { 110 checkTimeout(socketHandler, current); 111 } 112 113 } catch (ClosedSelectorException cse) { 114 watchDogTask.cancel(); 115 116 } catch (Exception e) { 117 if (LOG.isLoggable(Level.FINE)) { 118 LOG.fine("error occured: " + e.toString()); 119 } 120 } 121 } 122 123 private void checkTimeout(IoSocketHandler ioSocketHandler, long current) { 124 ioSocketHandler.checkConnection(); 125 126 127 boolean timeoutOccured = ioSocketHandler.checkIdleTimeout(current); 128 if (timeoutOccured) { 129 countIdleTimeouts++; 130 } 131 132 timeoutOccured = ioSocketHandler.checkConnectionTimeout(current); 133 if (timeoutOccured) { 134 countConnectionTimeouts++; 135 } 136 } 137 138 139 140 144 static boolean isDispatcherThread() { 145 return Thread.currentThread().getName().startsWith(DISPATCHER_PREFIX); 146 } 147 148 149 private static final class DispatcherEventHandler implements IEventHandler<IoSocketHandler> { 150 151 private IMemoryManager memoryManager = null; 152 153 DispatcherEventHandler(IMemoryManager memoryManager) { 154 this.memoryManager = memoryManager; 155 } 156 157 IMemoryManager getMemoryManager() { 158 return memoryManager; 159 } 160 161 162 public void onHandleReadableEvent(final IoSocketHandler socketIOHandler) throws IOException { 163 socketIOHandler.onReadableEvent(); 164 } 165 166 167 @SuppressWarnings ("unchecked") 168 public void onHandleWriteableEvent(final IoSocketHandler socketIOHandler) throws IOException { 169 socketIOHandler.onWriteableEvent(); 170 } 171 172 173 public void onHandleRegisterEvent(final IoSocketHandler socketIOHandler) throws IOException { 174 socketIOHandler.onConnectEvent(); 175 } 176 177 178 public void onDispatcherCloseEvent(final IoSocketHandler socketIOHandler) { 179 socketIOHandler.onDispatcherClose(); 180 } 181 } 182 } 183 | Popular Tags |