< prev index next >

src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/SessionManager.java

Print this page

        

@@ -32,11 +32,11 @@
 import sun.security.util.Debug;
 
 import sun.security.pkcs11.wrapper.*;
 import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
 
-import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * Session manager. There is one session manager object per PKCS#11
  * provider. It allows code to checkout a session, release it

@@ -110,12 +110,12 @@
             // choose an arbitrary concrete value
             n = DEFAULT_MAX_SESSIONS;
         }
         maxSessions = (int)Math.min(n, Integer.MAX_VALUE);
         this.token = token;
-        this.objSessions = new Pool(this);
-        this.opSessions = new Pool(this);
+        this.objSessions = new Pool(this, true);
+        this.opSessions = new Pool(this, false);
         if (debug != null) {
             maxActiveSessionsLock = new Object();
         }
     }
 

@@ -234,41 +234,47 @@
     }
 
     public static final class Pool {
 
         private final SessionManager mgr;
+        private final AbstractQueue<Session> pool;
+        private final int SESSION_MAX = 5;
 
-        private final ConcurrentLinkedDeque<Session> pool;
-
-        Pool(SessionManager mgr) {
+        // Object session pools can contain unlimited sessions.
+        // Operation session pools are limited and enforced by the queue.
+        Pool(SessionManager mgr, boolean obj) {
            this.mgr = mgr;
-           pool = new ConcurrentLinkedDeque<Session>();
+            if (obj) {
+                pool = new LinkedBlockingQueue<Session>();
+            } else {
+                pool = new LinkedBlockingQueue<Session>(SESSION_MAX);
+            }
         }
 
         boolean remove(Session session) {
             return pool.remove(session);
         }
 
         Session poll() {
-            return pool.pollLast();
+            return pool.poll();
         }
 
         void release(Session session) {
-            pool.offer(session);
-            if (session.hasObjects()) {
-                return;
+            // Object session pools never return false, only Operation ones
+            if (!pool.offer(session)) {
+                mgr.closeSession(session);
+                free();
             }
-
-            int n = pool.size();
-            if (n < 5) {
-                return;
             }
 
+        // Free any old operation session if this queue is full
+        void free() {
+            int n = SESSION_MAX;
+            int i = 0;
             Session oldestSession;
             long time = System.currentTimeMillis();
-            int i = 0;
-            // Check if the session head is too old and continue through queue
+            // Check if the session head is too old and continue through pool
             // until only one is left.
             do {
                 oldestSession = pool.peek();
                 if (oldestSession == null || oldestSession.isLive(time) ||
                         !pool.remove(oldestSession)) {
< prev index next >