- /*
- * @(#)CorbaConnectionCacheBase.java 1.25 04/06/21
- *
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
-
- package com.sun.corba.se.impl.transport;
-
- import java.util.Collection;
- import java.util.Iterator;
-
- import com.sun.corba.se.pept.broker.Broker;
- import com.sun.corba.se.pept.transport.Connection;
- import com.sun.corba.se.pept.transport.ConnectionCache;
-
- import com.sun.corba.se.spi.logging.CORBALogDomains;
- import com.sun.corba.se.spi.orb.ORB;
- import com.sun.corba.se.spi.transport.CorbaConnectionCache;
-
- import com.sun.corba.se.impl.logging.ORBUtilSystemException;
- import com.sun.corba.se.impl.orbutil.ORBUtility;
-
- /**
- * @author Harold Carr
- */
- public abstract class CorbaConnectionCacheBase
- implements
- ConnectionCache,
- CorbaConnectionCache
- {
- protected ORB orb;
- protected long timestamp = 0;
- protected String cacheType;
- protected String monitoringName;
- protected ORBUtilSystemException wrapper;
-
- protected CorbaConnectionCacheBase(ORB orb, String cacheType,
- String monitoringName)
- {
- this.orb = orb;
- this.cacheType = cacheType;
- this.monitoringName = monitoringName;
- wrapper =ORBUtilSystemException.get(orb,CORBALogDomains.RPC_TRANSPORT);
- registerWithMonitoring();
- dprintCreation();
- }
-
- ////////////////////////////////////////////////////
- //
- // pept.transport.ConnectionCache
- //
-
- public String getCacheType()
- {
- return cacheType;
- }
-
- public synchronized void stampTime(Connection c)
- {
- // _REVISIT_ Need to worry about wrap around some day
- c.setTimeStamp(timestamp++);
- }
-
- public long numberOfConnections()
- {
- synchronized (backingStore()) {
- return values().size();
- }
- }
-
- public long numberOfIdleConnections()
- {
- long count = 0;
- synchronized (backingStore()) {
- Iterator connections = values().iterator();
- while (connections.hasNext()) {
- if (! ((Connection)connections.next()).isBusy()) {
- count++;
- }
- }
- }
- return count;
- }
-
- public long numberOfBusyConnections()
- {
- long count = 0;
- synchronized (backingStore()) {
- Iterator connections = values().iterator();
- while (connections.hasNext()) {
- if (((Connection)connections.next()).isBusy()) {
- count++;
- }
- }
- }
- return count;
- }
-
- /**
- * Discarding least recently used Connections that are not busy
- *
- * This method must be synchronized since one WorkerThread could
- * be reclaming connections inside the synchronized backingStore
- * block and a second WorkerThread (or a SelectorThread) could have
- * already executed the if (numberOfConnections <= .... ). As a
- * result the second thread would also attempt to reclaim connections.
- *
- * If connection reclamation becomes a performance issue, the connection
- * reclamation could make its own task and consequently executed in
- * a separate thread.
- * Currently, the accept & reclaim are done in the same thread, WorkerThread
- * by default. It could be changed such that the SelectorThread would do
- * it for SocketChannels and WorkerThreads for Sockets by updating the
- * ParserTable.
- */
- synchronized public boolean reclaim()
- {
- try {
- long numberOfConnections = numberOfConnections();
-
- if (orb.transportDebugFlag) {
- dprint(".reclaim->: " + numberOfConnections
- + " ("
- + orb.getORBData().getHighWaterMark()
- + "/"
- + orb.getORBData().getLowWaterMark()
- + "/"
- + orb.getORBData().getNumberToReclaim()
- + ")");
- }
-
- if (numberOfConnections <= orb.getORBData().getHighWaterMark() ||
- numberOfConnections < orb.getORBData().getLowWaterMark()) {
- return false;
- }
-
- Object backingStore = backingStore();
- synchronized (backingStore) {
-
- // REVISIT - A less expensive alternative connection reclaiming
- // algorithm could be investigated.
-
- for (int i=0; i < orb.getORBData().getNumberToReclaim(); i++) {
- Connection toClose = null;
- long lru = java.lang.Long.MAX_VALUE;
- Iterator iterator = values().iterator();
-
- // Find least recently used and not busy connection in cache
- while ( iterator.hasNext() ) {
- Connection c = (Connection) iterator.next();
- if ( !c.isBusy() && c.getTimeStamp() < lru ) {
- toClose = c;
- lru = c.getTimeStamp();
- }
- }
-
- if ( toClose == null ) {
- return false;
- }
-
- try {
- if (orb.transportDebugFlag) {
- dprint(".reclaim: closing: " + toClose);
- }
- toClose.close();
- } catch (Exception ex) {
- // REVISIT - log
- }
- }
-
- if (orb.transportDebugFlag) {
- dprint(".reclaim: connections reclaimed ("
- + (numberOfConnections - numberOfConnections()) + ")");
- }
- }
-
- // XXX is necessary to do a GC to reclaim
- // closed network connections ??
- // java.lang.System.gc();
-
- return true;
- } finally {
- if (orb.transportDebugFlag) {
- dprint(".reclaim<-: " + numberOfConnections());
- }
- }
- }
-
- ////////////////////////////////////////////////////
- //
- // spi.transport.ConnectionCache
- //
-
- public String getMonitoringName()
- {
- return monitoringName;
- }
-
- ////////////////////////////////////////////////////
- //
- // Implementation
- //
-
- // This is public so folb.Server test can access it.
- public abstract Collection values();
-
- protected abstract Object backingStore();
-
- protected abstract void registerWithMonitoring();
-
- protected void dprintCreation()
- {
- if (orb.transportDebugFlag) {
- dprint(".constructor: cacheType: " + getCacheType()
- + " monitoringName: " + getMonitoringName());
- }
- }
-
- protected void dprintStatistics()
- {
- if (orb.transportDebugFlag) {
- dprint(".stats: "
- + numberOfConnections() + "/total "
- + numberOfBusyConnections() + "/busy "
- + numberOfIdleConnections() + "/idle"
- + " ("
- + orb.getORBData().getHighWaterMark() + "/"
- + orb.getORBData().getLowWaterMark() + "/"
- + orb.getORBData().getNumberToReclaim()
- + ")");
- }
- }
-
- protected void dprint(String msg)
- {
- ORBUtility.dprint("CorbaConnectionCacheBase", msg);
- }
- }
-
- // End of file.