| /* |
| * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package com.sun.jndi.ldap.pool; |
| |
| /** |
| * Represents a description of PooledConnection in Connections. |
| * Contains a PooledConnection, its state (busy, idle, expired), and idle time. |
| * |
| * Any access or update to a descriptor's state is synchronized. |
| * |
| * @author Rosanna Lee |
| */ |
| final class ConnectionDesc { |
| private final static boolean debug = Pool.debug; |
| |
| // Package private because used by Pool.showStats() |
| static final byte BUSY = (byte)0; |
| static final byte IDLE = (byte)1; |
| static final byte EXPIRED = (byte)2; |
| |
| final private PooledConnection conn; |
| |
| private byte state = IDLE; // initial state |
| private long idleSince; |
| private long useCount = 0; // for stats & debugging only |
| |
| ConnectionDesc(PooledConnection conn) { |
| this.conn = conn; |
| } |
| |
| ConnectionDesc(PooledConnection conn, boolean use) { |
| this.conn = conn; |
| if (use) { |
| state = BUSY; |
| ++useCount; |
| } |
| } |
| |
| /** |
| * Two desc are equal if their PooledConnections are the same. |
| * This is useful when searching for a ConnectionDesc using only its |
| * PooledConnection. |
| */ |
| public boolean equals(Object obj) { |
| return obj != null |
| && obj instanceof ConnectionDesc |
| && ((ConnectionDesc)obj).conn == conn; |
| } |
| |
| /** |
| * Hashcode is that of PooledConnection to facilitate |
| * searching for a ConnectionDesc using only its PooledConnection. |
| */ |
| public int hashCode() { |
| return conn.hashCode(); |
| } |
| |
| /** |
| * Changes the state of a ConnectionDesc from BUSY to IDLE and |
| * records the current time so that we will know how long it has been idle. |
| * @return true if state change occurred. |
| */ |
| synchronized boolean release() { |
| d("release()"); |
| if (state == BUSY) { |
| state = IDLE; |
| |
| idleSince = System.currentTimeMillis(); |
| return true; // Connection released, ready for reuse |
| } else { |
| return false; // Connection wasn't busy to begin with |
| } |
| } |
| |
| /** |
| * If ConnectionDesc is IDLE, change its state to BUSY and return |
| * its connection. |
| * |
| * @return ConnectionDesc's PooledConnection if it was idle; null otherwise. |
| */ |
| synchronized PooledConnection tryUse() { |
| d("tryUse()"); |
| |
| if (state == IDLE) { |
| state = BUSY; |
| ++useCount; |
| return conn; |
| } |
| |
| return null; |
| } |
| |
| /** |
| * If ConnectionDesc is IDLE and has expired, close the corresponding |
| * PooledConnection. |
| * |
| * @param threshold a connection that has been idle before this time |
| * have expired. |
| * |
| * @return true if entry is idle and has expired; false otherwise. |
| */ |
| synchronized boolean expire(long threshold) { |
| if (state == IDLE && idleSince < threshold) { |
| |
| d("expire(): expired"); |
| |
| state = EXPIRED; |
| conn.closeConnection(); // Close real connection |
| |
| return true; // Expiration successful |
| } else { |
| d("expire(): not expired"); |
| return false; // Expiration did not occur |
| } |
| } |
| |
| public String toString() { |
| return conn.toString() + " " + |
| (state == BUSY ? "busy" : (state == IDLE ? "idle" : "expired")); |
| } |
| |
| // Used by Pool.showStats() |
| int getState() { |
| return state; |
| } |
| |
| // Used by Pool.showStats() |
| long getUseCount() { |
| return useCount; |
| } |
| |
| private void d(String msg) { |
| if (debug) { |
| System.err.println("ConnectionDesc." + msg + " " + toString()); |
| } |
| } |
| } |