1 26 27 package org.objectweb.jonathan.libs.resources.tcpip; 28 29 import java.io.IOException ; 30 31 import org.objectweb.jonathan.apis.kernel.JonathanException; 32 import org.objectweb.jonathan.apis.protocols.ip.IpConnection; 33 import org.objectweb.jonathan.apis.protocols.ip.IpSession; 34 import org.objectweb.jonathan.apis.protocols.ip.TcpIpConnectionMgr; 35 import org.objectweb.jonathan.apis.protocols.ip.TcpIpSrvConnectionFactory; 36 import org.objectweb.jonathan.apis.resources.Chunk; 37 38 41 public class JConnectionMgr implements TcpIpConnectionMgr { 42 43 Connection[] connections = new Connection[101]; 44 int connects; 45 SrvConnectionFactory server_connection_factories; 46 47 Connection first_idle; 48 Connection last_idle; 49 int idle; 50 51 protected TcpIpConnectionMgr factory; 52 53 58 public int max_idle; 59 60 65 public JConnectionMgr(int max_idle,TcpIpConnectionMgr connection_factory) { 66 connects = 0; 67 this.max_idle = max_idle; 68 this.factory = connection_factory; 69 } 70 71 76 public String getCanonicalHostName(String hostname) { 77 return factory.getCanonicalHostName(hostname); 78 } 79 80 95 public synchronized IpConnection newCltConnection(String host, int port, 96 IpSession session) 97 throws JonathanException { 98 host = getCanonicalHostName(host); 99 int hash = host.hashCode() + port; 100 int len = connections.length; 101 int index = (hash & 0x7FFFFFFF) % len; 102 Connection connection = connections[index]; 103 while (connection != null) { 104 if (connection.getPort() == port && 105 connection.getHostName().equals(host)) { 106 if (connection.getSession() == null) { 107 connection.acquire(); 108 connection.setSession(session); 109 return connection; 110 } else if (connection.getSession().equals(session)) { 111 connection.acquire(); 112 return connection; 113 } 114 } 115 connection = connection.next; 116 } 117 connection = 118 newCltConnection(factory.newCltConnection(host,port,session)); 119 Connection first = connections[index]; 120 connections[index] = connection; 121 connection.next = first; 122 connects++; 123 if (connects > len / 2) { 124 rehash(len); 125 } 126 return connection; 127 } 128 129 136 public TcpIpSrvConnectionFactory newSrvConnectionFactory(int port) 137 throws JonathanException { 138 SrvConnectionFactory fac = server_connection_factories; 139 while (fac != null) { 140 if (fac.getPort() == port) { 141 break; 142 } 143 fac = fac.next; 144 } 145 if (fac == null) { 146 fac = server_connection_factories; 147 server_connection_factories = 148 new SrvConnectionFactory(factory.newSrvConnectionFactory(port)); 149 server_connection_factories.next = fac; 150 return server_connection_factories; 151 } else { 152 return fac; 153 } 154 } 155 156 163 protected Connection newCltConnection(IpConnection connection) 164 throws JonathanException { 165 return new Connection(connection); 166 } 167 168 172 void remove(Connection connection) { 173 int hash = connection.hashCode(); 174 int len = connections.length; 175 int index = (hash & 0x7FFFFFFF) % len; 176 Connection current = connections[index]; 177 Connection prev = null; 178 while (current != null) { 179 if (connection == current) { 180 if (prev == null) { 181 connections[index] = current.next; 182 } else { 183 prev.next = current.next; 184 } 185 return; 186 } else { 187 current = current.next; 188 } 189 } 190 } 191 192 void add(Connection connection) { 193 int hash = connection.hashCode(); 194 int len = connections.length; 195 int index = (hash & 0x7FFFFFFF) % len; 196 Connection first = connections[index]; 197 connections[index] = connection; 198 connection.next = first; 199 connects++; 200 if (connects > len / 2) { 201 rehash(len); 202 } 203 } 204 205 void removeConnectionFactory(SrvConnectionFactory factory) { 206 SrvConnectionFactory connection_factory = 207 server_connection_factories, prev = null; 208 while (connection_factory != null) { 209 if (connection_factory == factory) { 210 if (prev != null) { 211 prev.next = connection_factory.next; 212 } else { 213 server_connection_factories = connection_factory.next; 214 } 215 return; 216 } 217 prev = connection_factory; 218 connection_factory = connection_factory.next; 219 } 220 } 221 222 223 void rehash(int len) { 225 Connection entry, next_entry, first_entry; 226 int index; 227 int new_len = 2 * len + 1; 228 Connection[] new_table = new Connection[new_len]; 229 230 for (int i = 0; i < len; i++) { 231 entry = connections[i]; 232 while (entry != null) { 233 next_entry = entry.next; 234 index = (entry.hashCode() & 0x7FFFFFFF) % new_len; 236 first_entry = new_table[index]; 237 new_table[index] = entry; 238 entry.next = first_entry; 239 entry = next_entry; 241 } 242 } 243 connections = new_table; 244 } 245 246 249 public class Connection implements IpConnection { 250 251 Connection next_idle; 252 253 Connection prev_idle; 254 255 int acquired; 256 257 Connection next; 258 259 IpConnection delegate; 260 261 267 protected Connection(IpConnection delegate) { 268 this.delegate = delegate; 269 acquired = 1; 270 } 271 272 public int available() throws IOException { 273 return delegate.available(); 274 } 275 276 public void receive(Chunk chunk,int to_read) throws IOException { 277 delegate.receive(chunk,to_read); 278 } 279 280 public void emit(Chunk chunk) throws IOException { 281 delegate.emit(chunk); 282 } 283 284 288 public int getPort() { 289 return delegate.getPort(); 290 } 291 292 296 public String getHostName() { 297 return delegate.getHostName(); 298 } 299 300 304 public IpSession getSession() { 305 return delegate.getSession(); 306 } 307 308 309 313 public void setSession(IpSession session) { 314 delegate.setSession(session); 315 } 316 317 323 public void delete() { 324 synchronized(JConnectionMgr.this) { 325 delegate.delete(); 326 withdraw(); 327 } 328 } 329 330 335 public void acquire() { 336 synchronized(JConnectionMgr.this) { 337 acquired++; 338 if (acquired == 1) { 339 if (prev_idle != null) { 340 prev_idle.next_idle = next_idle; 341 } else { 342 first_idle = next_idle; 343 } 344 if (next_idle != null) { 345 next_idle.prev_idle = prev_idle; 346 } else { 347 last_idle = prev_idle; 348 } 349 prev_idle = next_idle = null; 350 idle--; 351 } 352 } 353 } 354 355 359 public void release() { 360 synchronized(JConnectionMgr.this) { 361 acquired--; 362 if (acquired == 0) { 363 if (last_idle != null) { 364 last_idle.next_idle = this; 365 last_idle = this; 366 } else { 367 last_idle = first_idle = this; 368 } 369 if (idle >= max_idle) { 370 first_idle.delegate.release(); 371 first_idle.withdraw(); 372 } 373 idle++; 374 } 375 } 376 } 377 378 void withdraw() { 379 remove(this); 380 if (next_idle != null) { 381 if (prev_idle != null) { 382 prev_idle.next_idle = next_idle; 383 next_idle.prev_idle = prev_idle; 384 } else { 385 first_idle = next_idle; 386 next_idle.prev_idle = null; 387 } 388 idle--; 389 } else if (prev_idle != null) { 390 last_idle = prev_idle; 391 prev_idle.next_idle = null; 392 idle--; 393 } else if (last_idle == this) { 394 last_idle = null; 396 prev_idle = null; 397 idle--; 398 } 399 } 400 401 public String toString() { 402 return "JConnectionMgr.Connection" + System.identityHashCode(this) 403 + "[" + delegate + "]"; 404 } 405 406 public int hashCode() { 407 int hashcode = delegate.getPort() + delegate.getHostName().hashCode(); 408 return hashcode; 409 } 410 } 411 412 class SrvConnectionFactory implements TcpIpSrvConnectionFactory { 413 414 TcpIpSrvConnectionFactory delegate; 415 SrvConnectionFactory next; 416 417 SrvConnectionFactory(TcpIpSrvConnectionFactory delegate) 418 throws JonathanException { 419 this.delegate = delegate; 420 } 421 422 public IpConnection newSrvConnection(IpSession session) 423 throws JonathanException { 424 return delegate.newSrvConnection(session); 425 } 426 427 public int getPort() { 428 return delegate.getPort(); 429 } 430 431 public String getHostName() { 432 return delegate.getHostName(); 433 } 434 435 public void close() { 436 synchronized(JConnectionMgr.this) { 437 delegate.close(); 438 removeConnectionFactory(this); 439 } 440 } 441 } 442 } 443 444 445 446 447 448 | Popular Tags |