Hi Team,
For the performance degrade we observed in our case on Windows platform only,
did some research and have few findings. Check below details and share your
thoughts and opinion.
Use Case:
-----------
Environment:
Platform: Windows Server (2025/2022)
OpenLDAP Version: 2.6.7 C SDK
LDAP Provider: Switching from Mozilla NSLDAP 6.0.7 to OpenLDAP 2.6.7
Connection Pattern: Single LDAP connection handle shared across multiple threads
API Usage: Synchronous calls (ldap_search_ext_s, ldap_bind_s,
ldap_get_values_len)
Problem Statement:
Significant performance degradation observed only on Windows when using
OpenLDAP 2.6.7, compared to Mozilla NSLDAP 6.0.7 in identical scenarios.
Research analysis and probable root cause:
------------------------------------------------
Key Observation:
Performance issue is Windows-specific and OpenLDAP-specific.
Both OpenLDAP and NSLDAP make identical network calls to LDAP server
No client-side caching differences
Server response times are identical
Conclusion: Issue is client-side, not network or server-related
Application Code Analysis:
Analyzed ldap_dup() usage (thread-local handles)
Removed ldap_dup() - degradation persisted
Conclusion: Issue is not in application logic
OpenLDAP Source Code Analysis:
After analyzing the OpenLDAP source code, identified one place where we
observed code difference between Windows and Linux platform.
In File: thr_nt.c, where wrappers implemented around NT threads
(ldap_pvt_thread_mutex_***).
Used HANDLE-based Windows Mutex (CreateMutex, WaitForSingleObject, ReleaseMutex)
Changes Implemented:
--------------------------
Replaced Windows Mutex with CRITICAL_SECTION
Change 1: Type Definition
File: include/ldap_int_thread.h
// BEFORE:
typedef HANDLE ldap_int_thread_mutex_t;
#define LDAP_INT_MUTEX_NULL ((HANDLE)0)
// AFTER:
typedef CRITICAL_SECTION ldap_int_thread_mutex_t;
#define LDAP_INT_MUTEX_NULL {0}
Change 2: Mutex Functions (updated Mutex functions to use Critical Section)
File: libraries/libldap/thr_nt.c
Functions:
ldap_int_mutex_firstcreate
ldap_pvt_thread_cond_wait
ldap_pvt_thread_cond_broadcast
ldap_pvt_thread_mutex_init
ldap_pvt_thread_mutex_recursive_init
ldap_pvt_thread_mutex_destroy
ldap_pvt_thread_mutex_lock
ldap_pvt_thread_mutex_unlock
ldap_pvt_thread_mutex_trylock
Ex:
int
ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex )
{
InitializeCriticalSection( mutex );
return 0;
}
int
ldap_pvt_thread_mutex_lock( ldap_pvt_thread_mutex_t *mutex )
{
EnterCriticalSection( mutex );
return 0;
}
After making these changes, build OpenLDAP library and verified with our
Application. Now, we are not getting any performance degrade on Windows
platform. Performance results are almost inline with existing Mozilla nsldap.
Your thoughts/Opinion request:
-----------------------------------
Are there existing recommendations or workarounds for high-concurrency Windows
deployments with shared LDAP handles?
Would a CRITICAL_SECTION implementation be acceptable, or are there concerns we
haven't considered?
We would greatly appreciate your thoughts on:
- Whether this is the right direction for Windows performance
- Any concerns or edge cases we should address
- Any other regression areas we should consider with this change
Thank you for maintaining OpenLDAP and for considering this request!