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!

Reply via email to