aboutsummaryrefslogtreecommitdiff
path: root/src/share/classes/sun/security/pkcs11/SessionManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/share/classes/sun/security/pkcs11/SessionManager.java')
-rw-r--r--src/share/classes/sun/security/pkcs11/SessionManager.java66
1 files changed, 28 insertions, 38 deletions
diff --git a/src/share/classes/sun/security/pkcs11/SessionManager.java b/src/share/classes/sun/security/pkcs11/SessionManager.java
index caf18ffc0..aed0264dd 100644
--- a/src/share/classes/sun/security/pkcs11/SessionManager.java
+++ b/src/share/classes/sun/security/pkcs11/SessionManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2010 Sun Microsystems, Inc. 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
@@ -51,10 +51,12 @@ import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
* number of such sessions low. Note that we occasionally want to explicitly
* close a session, see P11Signature.
*
- * NOTE that all sessions obtained from this class MUST be returned using
- * either releaseSession() or closeSession() using a finally block or a
- * finalizer where appropriate. Otherwise, they will be "lost", i.e. there
- * will be a resource leak eventually leading to exhaustion.
+ * NOTE that sessions obtained from this class SHOULD be returned using
+ * either releaseSession() or closeSession() using a finally block when
+ * not needed anymore. Otherwise, they will be left for cleanup via the
+ * PhantomReference mechanism when GC kicks in, but it's best not to rely
+ * on that since GC may not run timely enough since the native PKCS11 library
+ * is also consuming memory.
*
* Note that sessions are automatically closed when they are not used for a
* period of time, see Session.
@@ -74,9 +76,6 @@ final class SessionManager {
// maximum number of sessions to open with this token
private final int maxSessions;
- // total number of active sessions
- private int activeSessions;
-
// pool of available object sessions
private final Pool objSessions;
@@ -116,6 +115,11 @@ final class SessionManager {
return (maxSessions <= DEFAULT_MAX_SESSIONS);
}
+ // returns the total number of active sessions
+ int totalSessionCount() {
+ return SessionRef.totalCount();
+ }
+
synchronized Session getObjSession() throws PKCS11Exception {
Session session = objSessions.poll();
if (session != null) {
@@ -136,7 +140,8 @@ final class SessionManager {
}
// create a new session rather than re-using an obj session
// that avoids potential expensive cancels() for Signatures & RSACipher
- if (activeSessions < maxSessions) {
+ if (maxSessions == Integer.MAX_VALUE ||
+ totalSessionCount() < maxSessions) {
session = openSession();
return ensureValid(session);
}
@@ -159,14 +164,10 @@ final class SessionManager {
if (debug != null) {
String location = new Exception().getStackTrace()[2].toString();
System.out.println("Killing session (" + location + ") active: "
- + activeSessions);
- }
- try {
- closeSession(session);
- return null;
- } catch (PKCS11Exception e) {
- throw new ProviderException(e);
+ + totalSessionCount());
}
+ closeSession(session);
+ return null;
}
synchronized Session releaseSession(Session session) {
@@ -187,7 +188,8 @@ final class SessionManager {
return;
}
if (debug != null) {
- System.out.println("Demoting session, active: " + activeSessions);
+ System.out.println("Demoting session, active: " +
+ totalSessionCount());
}
boolean present = objSessions.remove(session);
if (present == false) {
@@ -199,16 +201,17 @@ final class SessionManager {
}
private Session openSession() throws PKCS11Exception {
- if (activeSessions >= maxSessions) {
+ if ((maxSessions != Integer.MAX_VALUE) &&
+ (totalSessionCount() >= maxSessions)) {
throw new ProviderException("No more sessions available");
}
long id = token.p11.C_OpenSession
(token.provider.slotID, openSessionFlags, null, null);
Session session = new Session(token, id);
- activeSessions++;
if (debug != null) {
- if (activeSessions > maxActiveSessions) {
- maxActiveSessions = activeSessions;
+ int currTotal = totalSessionCount();
+ if (currTotal > maxActiveSessions) {
+ maxActiveSessions = currTotal;
if (maxActiveSessions % 10 == 0) {
System.out.println("Open sessions: " + maxActiveSessions);
}
@@ -217,13 +220,8 @@ final class SessionManager {
return session;
}
- private void closeSession(Session session) throws PKCS11Exception {
- if (session.hasObjects()) {
- throw new ProviderException
- ("Internal error: close session with active objects");
- }
- token.p11.C_CloseSession(session.id());
- activeSessions--;
+ private void closeSession(Session session) {
+ session.close();
}
private static final class Pool {
@@ -267,28 +265,20 @@ final class SessionManager {
}
Collections.sort(pool);
int i = 0;
- PKCS11Exception exc = null;
while (i < n - 1) { // always keep at least 1 session open
oldestSession = pool.get(i);
if (oldestSession.isLive(time)) {
break;
}
i++;
- try {
- mgr.closeSession(oldestSession);
- } catch (PKCS11Exception e) {
- exc = e;
- }
+ mgr.closeSession(oldestSession);
}
if (debug != null) {
System.out.println("Closing " + i + " idle sessions, active: "
- + mgr.activeSessions);
+ + mgr.totalSessionCount());
}
List<Session> subList = pool.subList(0, i);
subList.clear();
- if (exc != null) {
- throw new ProviderException(exc);
- }
}
}