From a31f983e00638317675dbc8c28d082ee545c6e30 Mon Sep 17 00:00:00 2001 From: Valera V Harseko Date: Thu, 2 Jul 2026 18:52:12 +0300 Subject: [PATCH] Avoid global monitor on every bind in getDefaultPasswordPolicy getDefaultPasswordPolicy() took the authenticationPolicies monitor on every call just to read an already-cached value, and the method is called for every authentication. Under concurrent BIND load JFR shows worker threads blocking on this monitor (96 contention events / ~2 s blocked per 80 s window at 16 worker threads once other bind-path locks are removed). Make the defaultPasswordPolicy cache volatile and read it lock-free, falling back to the existing synchronized slow path only when the cache is empty (startup or configuration change). All mutations already happen under the authenticationPolicies monitor. --- .../opends/server/core/DirectoryServer.java | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java b/opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java index e5eeb614e8..dd9b8cb334 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java @@ -13,7 +13,7 @@ * * Copyright 2006-2010 Sun Microsystems, Inc. * Portions Copyright 2010-2016 ForgeRock AS. - * Portions Copyright 2022-2025 3A Systems, LLC. + * Portions Copyright 2022-2026 3A Systems, LLC. * Portions Copyright 2025 Wren Security. */ package org.opends.server.core; @@ -466,8 +466,12 @@ public final class DirectoryServer /** The configuration handler used to manage the password generators. */ private PasswordGeneratorConfigManager passwordGeneratorConfigManager; - /** The default password policy for the Directory Server. */ - private PasswordPolicy defaultPasswordPolicy; + /** + * The default password policy for the Directory Server. Volatile so that + * getDefaultPasswordPolicy() can read the cached value without taking the + * authenticationPolicies monitor; all mutations happen under that monitor. + */ + private volatile PasswordPolicy defaultPasswordPolicy; /** The configuration handler used to manage the authentication policies. */ private PasswordPolicyConfigManager authenticationPolicyConfigManager; /** The configuration handler used to manage the password storage schemes. */ @@ -2535,6 +2539,15 @@ public static void resetDefaultPasswordPolicy() */ public static PasswordPolicy getDefaultPasswordPolicy() { + // This method is called on every authentication. Do not take the global + // monitor just to read the cached value: it is volatile and only mutated + // under the authenticationPolicies monitor. + PasswordPolicy cachedPolicy = directoryServer.defaultPasswordPolicy; + if (cachedPolicy != null) + { + return cachedPolicy; + } + // Ensure default policy is synchronized. synchronized (directoryServer.authenticationPolicies) {