1 16 package org.apache.tomcat.util.net; 17 18 import java.util.LinkedList ; 19 import java.util.concurrent.atomic.AtomicInteger ; 20 import java.nio.channels.Selector ; 21 import java.io.IOException ; 22 import java.util.NoSuchElementException ; 23 import java.nio.ByteBuffer ; 24 import java.nio.channels.SocketChannel ; 25 import java.nio.channels.SelectionKey ; 26 import java.io.EOFException ; 27 import java.net.SocketTimeoutException ; 28 import java.util.concurrent.ConcurrentLinkedQueue ; 29 30 37 38 public class NioSelectorPool { 39 protected int maxSelectors = 200; 40 protected int maxSpareSelectors = -1; 41 protected boolean enabled = true; 42 protected AtomicInteger active = new AtomicInteger (0); 43 protected AtomicInteger spare = new AtomicInteger (0); 44 protected ConcurrentLinkedQueue <Selector > selectors = new ConcurrentLinkedQueue <Selector >(); 46 47 public Selector get() throws IOException { 48 if ( (!enabled) || active.incrementAndGet() >= maxSelectors ) { 49 if ( enabled ) active.decrementAndGet(); 50 return null; 51 } 52 Selector s = null; 53 try { 54 s = selectors.size()>0?selectors.poll():null; 55 if (s == null) s = Selector.open(); 56 else spare.decrementAndGet(); 57 58 }catch (NoSuchElementException x ) { 59 try {s = Selector.open();}catch (IOException iox){} 60 } finally { 61 if ( s == null ) active.decrementAndGet(); } 63 return s; 64 } 65 66 67 68 public void put(Selector s) throws IOException { 69 if ( enabled ) active.decrementAndGet(); 70 if ( enabled && (maxSpareSelectors==-1 || spare.get() < Math.min(maxSpareSelectors,maxSelectors)) ) { 71 spare.incrementAndGet(); 72 selectors.offer(s); 73 } 74 else s.close(); 75 } 76 77 public void close() throws IOException { 78 enabled = false; 79 Selector s; 80 while ( (s = selectors.poll()) != null ) s.close(); 81 spare.set(0); 82 active.set(0); 83 } 84 85 public void open(){ 86 enabled = true; 87 } 88 89 102 public int write(ByteBuffer buf, NioChannel socket, Selector selector, long writeTimeout) throws IOException { 103 SelectionKey key = null; 104 int written = 0; 105 boolean timedout = false; 106 int keycount = 1; long time = System.currentTimeMillis(); try { 109 while ( (!timedout) && buf.hasRemaining() ) { 110 if ( keycount > 0 ) { int cnt = socket.write(buf); if (cnt == -1) throw new EOFException (); 113 written += cnt; 114 if (cnt > 0) { 115 time = System.currentTimeMillis(); continue; } 118 } 119 if ( selector != null ) { 120 if (key==null) key = socket.getIOChannel().register(selector, SelectionKey.OP_WRITE); 122 else key.interestOps(SelectionKey.OP_WRITE); 123 keycount = selector.select(writeTimeout); 124 } 125 if (writeTimeout > 0 && (selector == null || keycount == 0) ) timedout = (System.currentTimeMillis()-time)>=writeTimeout; 126 } if ( timedout ) throw new SocketTimeoutException (); 128 } finally { 129 if (key != null) { 130 key.cancel(); 131 if (selector != null) selector.selectNow(); } 133 } 134 return written; 135 } 136 137 150 public int read(ByteBuffer buf, NioChannel socket, Selector selector, long readTimeout) throws IOException { 151 SelectionKey key = null; 152 int read = 0; 153 boolean timedout = false; 154 int keycount = 1; long time = System.currentTimeMillis(); try { 157 while ( (!timedout) && read == 0 ) { 158 if ( keycount > 0 ) { int cnt = socket.read(buf); 160 if (cnt == -1) throw new EOFException (); 161 read += cnt; 162 if (cnt > 0) break; 163 } 164 if ( selector != null ) { 165 if (key==null) key = socket.getIOChannel().register(selector, SelectionKey.OP_READ); 167 else key.interestOps(SelectionKey.OP_READ); 168 keycount = selector.select(readTimeout); 169 } 170 if (readTimeout > 0 && (selector == null || keycount == 0) ) timedout = (System.currentTimeMillis()-time)>=readTimeout; 171 } if ( timedout ) throw new SocketTimeoutException (); 173 } finally { 174 if (key != null) { 175 key.cancel(); 176 if (selector != null) selector.selectNow(); } 178 } 179 return read; 180 } 181 182 public void setMaxSelectors(int maxSelectors) { 183 this.maxSelectors = maxSelectors; 184 } 185 186 public void setMaxSpareSelectors(int maxSpareSelectors) { 187 this.maxSpareSelectors = maxSpareSelectors; 188 } 189 190 public void setEnabled(boolean enabled) { 191 this.enabled = enabled; 192 } 193 194 public int getMaxSelectors() { 195 return maxSelectors; 196 } 197 198 public int getMaxSpareSelectors() { 199 return maxSpareSelectors; 200 } 201 202 public boolean isEnabled() { 203 return enabled; 204 } 205 } | Popular Tags |