From a09eacf853ccaabcf0a7b7f9f52bad5b45700d14 Mon Sep 17 00:00:00 2001 From: lilgreenbird Date: Mon, 25 Mar 2024 14:31:32 -0700 Subject: [PATCH 1/3] fix leak --- .../sqlserver/jdbc/ActivityCorrelator.java | 28 ++++++++++++++----- .../sqlserver/jdbc/SQLServerConnection.java | 4 +++ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/ActivityCorrelator.java b/src/main/java/com/microsoft/sqlserver/jdbc/ActivityCorrelator.java index 974ac3c47..a3991fa9b 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/ActivityCorrelator.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/ActivityCorrelator.java @@ -5,7 +5,9 @@ package com.microsoft.sqlserver.jdbc; +import java.util.Map; import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; /** @@ -13,15 +15,18 @@ */ final class ActivityCorrelator { - private static ThreadLocal t_ActivityId = new ThreadLocal() { - @Override - protected ActivityId initialValue() { - return new ActivityId(); - } - }; + private static Map activityIdMap = new ConcurrentHashMap(); static ActivityId getCurrent() { - return t_ActivityId.get(); + // get the value in TLS, not reference + long uniqueThreadId = Thread.currentThread().threadId(); + + // Since the Id for each thread is unique, this assures that the below if statement is run only once per thread. + if (!activityIdMap.containsKey(uniqueThreadId)) { + activityIdMap.put(uniqueThreadId, new ActivityId()); + } + + return activityIdMap.get(uniqueThreadId); } // Increment the Sequence number of the ActivityId in TLS @@ -34,6 +39,15 @@ static ActivityId getNext() { * Prevent instantiation. */ private ActivityCorrelator() {} + + static void cleanupActivityId() { + // remove the ActivityId that belongs to this thread. + long uniqueThreadId = Thread.currentThread().threadId(); + + if (activityIdMap.containsKey(uniqueThreadId)) { + activityIdMap.remove(uniqueThreadId); + } + } } diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java index 8012bea5c..ccc0f3698 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java @@ -4785,6 +4785,8 @@ private void clearConnectionResources() { // Clean-up queue etc. related to batching of prepared statement discard actions (sp_unprepare). cleanupPreparedStatementDiscardActions(); + + ActivityCorrelator.cleanupActivityId(); } /** @@ -4806,6 +4808,8 @@ final void poolCloseEventNotify() throws SQLServerException { } notifyPooledConnection(null); + ActivityCorrelator.cleanupActivityId(); + if (connectionlogger.isLoggable(Level.FINER)) { connectionlogger.finer(toString() + " Connection closed and returned to connection pool"); } From b24ced71430a67e80b4e097d3841e9fc6d3a9199 Mon Sep 17 00:00:00 2001 From: lilgreenbird Date: Mon, 25 Mar 2024 17:45:22 -0700 Subject: [PATCH 2/3] update to use jdk8 compat method --- .../com/microsoft/sqlserver/jdbc/ActivityCorrelator.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/ActivityCorrelator.java b/src/main/java/com/microsoft/sqlserver/jdbc/ActivityCorrelator.java index a3991fa9b..b50a18276 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/ActivityCorrelator.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/ActivityCorrelator.java @@ -19,7 +19,8 @@ final class ActivityCorrelator { static ActivityId getCurrent() { // get the value in TLS, not reference - long uniqueThreadId = Thread.currentThread().threadId(); + @SuppressWarnings("deprecation") + long uniqueThreadId = Thread.currentThread().getId(); // Since the Id for each thread is unique, this assures that the below if statement is run only once per thread. if (!activityIdMap.containsKey(uniqueThreadId)) { @@ -42,7 +43,8 @@ private ActivityCorrelator() {} static void cleanupActivityId() { // remove the ActivityId that belongs to this thread. - long uniqueThreadId = Thread.currentThread().threadId(); + @SuppressWarnings("deprecation") + long uniqueThreadId = Thread.currentThread().getId(); if (activityIdMap.containsKey(uniqueThreadId)) { activityIdMap.remove(uniqueThreadId); From e6b3e5f707a1b3c90219e7441fda4a471b44402f Mon Sep 17 00:00:00 2001 From: lilgreenbird Date: Tue, 26 Mar 2024 14:41:38 -0700 Subject: [PATCH 3/3] comments updates --- .../com/microsoft/sqlserver/jdbc/ActivityCorrelator.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/ActivityCorrelator.java b/src/main/java/com/microsoft/sqlserver/jdbc/ActivityCorrelator.java index b50a18276..072d34f51 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/ActivityCorrelator.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/ActivityCorrelator.java @@ -11,14 +11,14 @@ /** - * ActivityCorrelator provides the APIs to access the ActivityId in TLS + * ActivityCorrelator provides the APIs to access the ActivityId in a map */ final class ActivityCorrelator { private static Map activityIdMap = new ConcurrentHashMap(); static ActivityId getCurrent() { - // get the value in TLS, not reference + // get the value, not reference @SuppressWarnings("deprecation") long uniqueThreadId = Thread.currentThread().getId(); @@ -30,7 +30,7 @@ static ActivityId getCurrent() { return activityIdMap.get(uniqueThreadId); } - // Increment the Sequence number of the ActivityId in TLS + // Increment the Sequence number of the ActivityId // and return the ActivityId with new Sequence number static ActivityId getNext() { return getCurrent().getIncrement();