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!