8098580: drainRefQueueBounds() puts pressure on pool.size()
Reviewed-by: valeriep
This commit is contained in:
parent
82d451f3d7
commit
657cfea401
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -45,6 +45,7 @@ import sun.security.internal.interfaces.TlsMasterSecret;
|
|||||||
import sun.security.pkcs11.wrapper.*;
|
import sun.security.pkcs11.wrapper.*;
|
||||||
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
|
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
|
||||||
|
|
||||||
|
import sun.security.util.Debug;
|
||||||
import sun.security.util.DerValue;
|
import sun.security.util.DerValue;
|
||||||
import sun.security.util.Length;
|
import sun.security.util.Length;
|
||||||
import sun.security.util.ECUtil;
|
import sun.security.util.ECUtil;
|
||||||
@ -1110,11 +1111,41 @@ final class SessionKeyRef extends PhantomReference<P11Key>
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void drainRefQueueBounded() {
|
private static void drainRefQueueBounded() {
|
||||||
|
Session sess = null;
|
||||||
|
Token tkn = null;
|
||||||
while (true) {
|
while (true) {
|
||||||
SessionKeyRef next = (SessionKeyRef) refQueue.poll();
|
SessionKeyRef next = (SessionKeyRef) refQueue.poll();
|
||||||
if (next == null) break;
|
if (next == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the token is still valid, try to remove the object
|
||||||
|
if (next.session.token.isValid()) {
|
||||||
|
// If this key's token is the same as the previous key, the
|
||||||
|
// same session can be used for C_DestroyObject.
|
||||||
|
try {
|
||||||
|
if (next.session.token != tkn || sess == null) {
|
||||||
|
// Release session if not using previous token
|
||||||
|
if (tkn != null && sess != null) {
|
||||||
|
tkn.releaseSession(sess);
|
||||||
|
sess = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
tkn = next.session.token;
|
||||||
|
sess = tkn.getOpSession();
|
||||||
|
}
|
||||||
|
next.disposeNative(sess);
|
||||||
|
} catch (PKCS11Exception e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Regardless of native results, dispose of java references
|
||||||
next.dispose();
|
next.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tkn != null && sess != null) {
|
||||||
|
tkn.releaseSession(sess);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle to the native key
|
// handle to the native key
|
||||||
@ -1127,25 +1158,17 @@ final class SessionKeyRef extends PhantomReference<P11Key>
|
|||||||
this.session = session;
|
this.session = session;
|
||||||
this.session.addObject();
|
this.session.addObject();
|
||||||
refList.add(this);
|
refList.add(this);
|
||||||
// TBD: run at some interval and not every time?
|
|
||||||
drainRefQueueBounded();
|
drainRefQueueBounded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void disposeNative(Session s) throws PKCS11Exception {
|
||||||
|
session.token.p11.C_DestroyObject(s.id(), keyID);
|
||||||
|
}
|
||||||
|
|
||||||
private void dispose() {
|
private void dispose() {
|
||||||
refList.remove(this);
|
refList.remove(this);
|
||||||
if (session.token.isValid()) {
|
this.clear();
|
||||||
Session newSession = null;
|
session.removeObject();
|
||||||
try {
|
|
||||||
newSession = session.token.getOpSession();
|
|
||||||
session.token.p11.C_DestroyObject(newSession.id(), keyID);
|
|
||||||
} catch (PKCS11Exception e) {
|
|
||||||
// ignore
|
|
||||||
} finally {
|
|
||||||
this.clear();
|
|
||||||
session.token.releaseSession(newSession);
|
|
||||||
session.removeObject();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int compareTo(SessionKeyRef other) {
|
public int compareTo(SessionKeyRef other) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -34,7 +34,7 @@ import sun.security.util.Debug;
|
|||||||
import sun.security.pkcs11.wrapper.*;
|
import sun.security.pkcs11.wrapper.*;
|
||||||
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
|
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -112,8 +112,8 @@ final class SessionManager {
|
|||||||
}
|
}
|
||||||
maxSessions = (int)Math.min(n, Integer.MAX_VALUE);
|
maxSessions = (int)Math.min(n, Integer.MAX_VALUE);
|
||||||
this.token = token;
|
this.token = token;
|
||||||
this.objSessions = new Pool(this);
|
this.objSessions = new Pool(this, true);
|
||||||
this.opSessions = new Pool(this);
|
this.opSessions = new Pool(this, false);
|
||||||
if (debug != null) {
|
if (debug != null) {
|
||||||
maxActiveSessionsLock = new Object();
|
maxActiveSessionsLock = new Object();
|
||||||
}
|
}
|
||||||
@ -236,12 +236,18 @@ final class SessionManager {
|
|||||||
public static final class Pool {
|
public static final class Pool {
|
||||||
|
|
||||||
private final SessionManager mgr;
|
private final SessionManager mgr;
|
||||||
|
private final AbstractQueue<Session> pool;
|
||||||
|
private final int SESSION_MAX = 5;
|
||||||
|
|
||||||
private final ConcurrentLinkedDeque<Session> pool;
|
// Object session pools can contain unlimited sessions.
|
||||||
|
// Operation session pools are limited and enforced by the queue.
|
||||||
Pool(SessionManager mgr) {
|
Pool(SessionManager mgr, boolean obj) {
|
||||||
this.mgr = mgr;
|
this.mgr = mgr;
|
||||||
pool = new ConcurrentLinkedDeque<Session>();
|
if (obj) {
|
||||||
|
pool = new LinkedBlockingQueue<Session>();
|
||||||
|
} else {
|
||||||
|
pool = new LinkedBlockingQueue<Session>(SESSION_MAX);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean remove(Session session) {
|
boolean remove(Session session) {
|
||||||
@ -249,24 +255,24 @@ final class SessionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Session poll() {
|
Session poll() {
|
||||||
return pool.pollLast();
|
return pool.poll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void release(Session session) {
|
void release(Session session) {
|
||||||
pool.offer(session);
|
// Object session pools never return false, only Operation ones
|
||||||
if (session.hasObjects()) {
|
if (!pool.offer(session)) {
|
||||||
return;
|
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;
|
Session oldestSession;
|
||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
int i = 0;
|
// Check if the session head is too old and continue through pool
|
||||||
// Check if the session head is too old and continue through queue
|
|
||||||
// until only one is left.
|
// until only one is left.
|
||||||
do {
|
do {
|
||||||
oldestSession = pool.peek();
|
oldestSession = pool.peek();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user