do not try to register custom monitor stuff when subordinate (related to ITS#4965); note: this might not be the best solution, because it does not allow to monitor subordinate databases; however, right now it's necessary, since subodinate databases do not register themselves in back-monitor
Remove ltp_active_list. It became unneeded when rev 1.24 added thread_keys[].
Tighten loop in pool_pause(): Omit unneeded ltp_pcond signals since rev 1.64.
Fix comment.
Simplify: Remove tid_zero, thread_keys[].id and ldap_int_main_tid.
Not needed after ldap_int_thread_userctx_t.ltu_id was added and
_pool_wrapper took care not to update thread_keys[] during pauses.
Fix bogus thread_keys[].ctx comment.
In pool_submit():
- Move problematic mutex_unlock()-mutex_lock() into the unused #ifdef
LDAP_PVT_THREAD_POOL_SEM_LOAD_CONTROL and add a FIXME comment inside.
- Delay ltp_starting--; until pool_wrapper(). Nonzero value could otherwise
no longer be exposed when !defined LDAP_PVT_THREAD_POOL_SEM_LOAD_CONTROL.
libldap/tls.c calls CRYPTO_set_id_callback(ldap_pvt_thread_self), which
causes ldap_pvt_thread_self to be called with the wrong prototype.
That can cause OpenSSL to use a garbage value, e.g. if the unsigned
long it expects takes two words but ldap_pvt_thread_t is an int.
I'm fixing it in HEAD now and also provoking an error if unsigned
long cannot hold a ldap_pvt_thread_t. Otherwise it can silently
compile to broken code. Maybe the latter should go in configure,
but since OpenSSL presumably breaks anyway if that fails I don't
see much point at this time.
Give OperationBuffer normal struct members instead of using
LBER_ALIGNED_BUFFER(OPERATION_BUFFER_SIZE), as discussed in ITS#4078.
Add a corresponding SyncOperationBuffer in overlays/syncprov.c.
Since we only have LDAP_MAXTHR thread_keys, allow max LDAP_MAXTHR
threads per pool, even when ltp_max_count <= 0 ("unlimited").
Keep ltp_max_count in range [0, LDAP_MAXTHR].
Make ldap_int_thread_userctx_t.ltu_key[] a proper NULL-terminated array.
(setkey/getkey expected that, but purgekey could set a NULL in the middle.)
Added some checks for input key!=NULL.
API changes, need review - I'm not sure what's indented here:
- setkey(data=NULL, kfree!=NULL) searched as if intended to reset
the key, but updated by setting the key. Now always updates.
- setkey(key=<not found>, data=NULL) could return either success or
failure. Now succeeds iff (data == NULL && kfree == NULL).
thread_keys is a (poor) open-addessed hash table, but it lacked a
"deleted item" mark. Add DELETED_THREAD_CTX.
Also improve the hash function a bit, and make the hash unsigned.
Protect thread_keys[] with ldap_pvt_thread_pool_mutex, except in
ldap_pvt_thread_pool_purgekey() which may only be called during pauses.
Thus, also wait for pauses to finish before accessing thread_keys in
ldap_int_thread_pool_wrapper(). This may prevent pending tasks from
being started when a pause had been requested, which seems to have been
possible. If that was a feature, we can split ltp_pause==1 in 2 states:
in pause (causes wait), and pause requested.
Also move 'thread_keys[].id = <thread id>' from pool_submit to
pool_wrapper. Until pool_wrapper set the ctx as well, thread context
lookup would just return NULL anyway.
Replace state LDAP_INT_THREAD_POOL_PAUSING with member ltp_pause,
so a pause will work during states FINISHING and STOPPING.
Add missing waits and signals, and move waits in pool_wrapper().
Replace if(test) with while(test) when waiting for the multi-purpose
condition variable ltp_cond.
ITS#4943:
In ldap_pvt_thread_pool_submit(), when backing out of thread creation:
ltp_pending_count '++' -> '--'. Signal if there are no more threads.
In ldap_int_thread_pool_wrapper():
if() -> assert() where false would result in eternal loop.