]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
ITS#8901 ldap_pvt_thread: add _detach() support
authorHoward Chu <hyc@openldap.org>
Sat, 30 May 2026 13:43:16 +0000 (14:43 +0100)
committerQuanah Gibson-Mount <quanah@openldap.org>
Thu, 4 Jun 2026 18:02:30 +0000 (18:02 +0000)
Prep for fixups to tpool.

include/ldap_pvt_thread.h
libraries/libldap/ldap.map.in
libraries/libldap/ldap_thr_debug.h
libraries/libldap/thr_debug.c
libraries/libldap/thr_nt.c
libraries/libldap/thr_posix.c
libraries/libldap/thr_pth.c
libraries/libldap/thr_thr.c

index 500d8cdcab103518c7aa5815bff4e06067b6936d..14e5c1e05d93e647e0e4d644737978c891d5d005 100644 (file)
@@ -81,6 +81,9 @@ ldap_pvt_thread_create LDAP_P((
 LDAP_F( void )
 ldap_pvt_thread_exit LDAP_P(( void *retval ));
 
+LDAP_F( int )
+ldap_pvt_thread_detach LDAP_P(( ldap_pvt_thread_t thread ));
+
 LDAP_F( int )
 ldap_pvt_thread_join LDAP_P(( ldap_pvt_thread_t thread, void **status ));
 
index 1ef46ab2573a5572f9c0342cf3313bc3eea3f9de..e61f426f381bb25eb8e13d388116b1528600c5aa 100644 (file)
@@ -502,6 +502,7 @@ OPENLDAP_2.200
     ldap_pvt_thread_cond_wait;
     ldap_pvt_thread_create;
     ldap_pvt_thread_destroy;
+    ldap_pvt_thread_detach;
     ldap_pvt_thread_exit;
     ldap_pvt_thread_get_concurrency;
     ldap_pvt_thread_initialize;
index d1c03d307e85fc1f9347c1df85c81bd7f8594952..7d5b2db97bbb6412e869fa90787fd4ed4b9497d9 100644 (file)
@@ -74,6 +74,7 @@
 #define        ldap_pvt_thread_set_concurrency ldap_int_thread_set_concurrency
 #define        ldap_pvt_thread_create                  ldap_int_thread_create
 #define        ldap_pvt_thread_exit                    ldap_int_thread_exit
+#define        ldap_pvt_thread_detach                  ldap_int_thread_detach
 #define        ldap_pvt_thread_join                    ldap_int_thread_join
 #define        ldap_pvt_thread_kill                    ldap_int_thread_kill
 #define        ldap_pvt_thread_yield                   ldap_int_thread_yield
 #ifdef LDAP_THREAD_DEBUG_WRAP                  /* see ldap_pvt_thread.h */
 #define        ldap_pvt_thread_pool_t                  ldap_int_thread_pool_t
 #endif
-#define        ldap_pvt_thread_pool_init               ldap_int_thread_pool_init
+#define        ldap_pvt_thread_pool_init_q             ldap_int_thread_pool_init_q
 #define        ldap_pvt_thread_pool_submit             ldap_int_thread_pool_submit
 #define        ldap_pvt_thread_pool_maxthreads ldap_int_thread_pool_maxthreads
 #define        ldap_pvt_thread_pool_backload   ldap_int_thread_pool_backload
 #undef ldap_pvt_thread_set_concurrency
 #undef ldap_pvt_thread_create
 #undef ldap_pvt_thread_exit
+#undef ldap_pvt_thread_detach
 #undef ldap_pvt_thread_join
 #undef ldap_pvt_thread_kill
 #undef ldap_pvt_thread_yield
 #undef ldap_pvt_thread_rdwr_active
 /* LDAP_THREAD_POOL_IMPLEMENTATION: */
 #undef ldap_pvt_thread_pool_t
-#undef ldap_pvt_thread_pool_init
+#undef ldap_pvt_thread_pool_init_q
 #undef ldap_pvt_thread_pool_submit
 #undef ldap_pvt_thread_pool_maxthreads
 #undef ldap_pvt_thread_pool_backload
index fbbc666b81a7f655123bfecc05e370058d47ee06..a9d6796ab541de65b5519e097093ab266365aab3 100644 (file)
@@ -506,6 +506,7 @@ typedef void ldap_debug_thread_t;
 #define init_thread_info()     {}
 #define with_thread_info_lock(statements) { statements; }
 #define thread_info_detached(t)        0
+#define thread_info_set_detach(t)      0
 #define add_thread_info(msg, thr, det) ((void) 0)
 #define remove_thread_info(tinfo, msg) ((void) 0)
 #define get_thread_info(thread, msg)   NULL
@@ -548,6 +549,7 @@ static ldap_int_thread_mutex_t  thread_info_mutex;
 }
 
 #define thread_info_detached(t) ((t)->detached)
+#define thread_info_set_detach(t)      (t)->detached = 1
 
 static void
 add_thread_info(
@@ -822,6 +824,35 @@ ldap_pvt_thread_create(
        return rc;
 }
 
+int
+ldap_pvt_thread_detach( ldap_pvt_thread_t thread )
+{
+       int rc;
+       ldap_debug_thread_t *t = NULL;
+       ERROR_IF( !threading_enabled, "ldap_pvt_thread_detach" );
+       if( tracethreads ) {
+               char buf[40], buf2[40];
+               fprintf( stderr, "== thr_debug: Detaching thread %s in thread %s ==\n",
+                       thread_name( buf, sizeof(buf), thread ),
+                       thread_name( buf2, sizeof(buf2), ldap_pvt_thread_self() ) );
+       }
+       if( threadID )
+               with_thread_info_lock( {
+                       t = get_thread_info( thread, "ldap_pvt_thread_detach" );
+                       ERROR_IF( thread_info_detached( t ), "ldap_pvt_thread_detach" );
+               } );
+       rc = ldap_int_thread_detach( thread );
+       if( rc ) {
+               ERROR( rc, "ldap_pvt_thread_detach" );
+       } else {
+               if( threadID )
+                       with_thread_info_lock(
+                               thread_info_set_detach( t ) );
+               adjust_count( Idx_unjoined_thread, -1 );
+       }
+       return rc;
+}
+
 int
 ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return )
 {
@@ -1171,18 +1202,19 @@ ldap_pvt_thread_rdwr_active( ldap_pvt_thread_rdwr_t *rwlock )
 #ifdef LDAP_THREAD_POOL_IMPLEMENTATION
 
 int
-ldap_pvt_thread_pool_init(
+ldap_pvt_thread_pool_init_q(
        ldap_pvt_thread_pool_t *tpool,
        int max_threads,
-       int max_pending )
+       int max_pending,
+       int num_queues )
 {
        int rc;
        if( !options_done )
                get_options();
        ERROR_IF( !threading_enabled, "ldap_pvt_thread_pool_init" );
-       rc = ldap_int_thread_pool_init( tpool, max_threads, max_pending );
+       rc = ldap_int_thread_pool_init_q( tpool, max_threads, max_pending, num_queues );
        if( rc ) {
-               ERROR( rc, "ldap_pvt_thread_pool_init" );
+               ERROR( rc, "ldap_pvt_thread_pool_init_q" );
        } else {
                adjust_count( Idx_tpool, +1 );
        }
index cf096e50f73a4389addb925df40d047e615d8c33..6b3b6d3c88d949c5212a655914e1edee02a3daff 100644 (file)
@@ -38,6 +38,7 @@ typedef struct ldap_int_thread_s {
 static ldap_int_thread_s tids[NT_MAX_THREADS];
 static int ntids;
 
+static ldap_pvt_thread_mutex_t tid_mutex;
 
 /* mingw compiler very sensitive about getting prototypes right */
 typedef unsigned __stdcall thrfunc_t(void *);
@@ -45,12 +46,14 @@ typedef unsigned __stdcall thrfunc_t(void *);
 int
 ldap_int_thread_initialize( void )
 {
+       ldap_pvt_thread_mutex_init( &tid_mutex );
        return 0;
 }
 
 int
 ldap_int_thread_destroy( void )
 {
+       ldap_pvt_thread_mutex_destroy( &tid_mutex );
        return 0;
 }
 
@@ -80,9 +83,11 @@ ldap_pvt_thread_create( ldap_pvt_thread_t * thread,
 
        if ( thd ) {
                *thread = (ldap_pvt_thread_t) tid;
+               ldap_pvt_thread_mutex_lock( &tid_mutex );
                tids[ntids].tid = tid;
                tids[ntids].thd = thd;
                ntids++;
+               ldap_pvt_thread_mutex_unlock( &tid_mutex );
                rc = 0;
        }
        return rc;
@@ -91,27 +96,59 @@ ldap_pvt_thread_create( ldap_pvt_thread_t * thread,
 void 
 ldap_pvt_thread_exit( void *retval )
 {
-       _endthread( );
+       _endthreadex( (unsigned int)retval );
 }
 
-int 
-ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return )
+static int
+ldap_pvt_thread_pop( ldap_pvt_thread_t thread, HANDLE *thd )
 {
-       DWORD status;
-       int i;
+       int i, rc = -1;
 
-       for (i=0; i<ntids; i++) {
+       ldap_pvt_thread_mutex_lock( &tid_mutex );
+       for ( i=0; i<ntids; i++ ) {
                if ( tids[i].tid == thread )
                        break;
        }
-       if ( i > ntids ) return -1;
+       if ( i<ntids ) {
+               *thd = tids[i].thd;
+               for (; i<ntids; i++) {
+                       tids[i] = tids[i+1];
+               }
+               ntids--;
+               rc = 0;
+       }
+       ldap_pvt_thread_mutex_unlock( &tid_mutex );
+       return rc;
+}
+
+int
+ldap_pvt_thread_detach( ldap_pvt_thread_t thread )
+{
+       HANDLE thd;
+       int rc = ldap_pvt_thread_pop( thread, &thd );
 
-       status = WaitForSingleObject( tids[i].thd, INFINITE );
-       for (; i<ntids; i++) {
-               tids[i] = tids[i+1];
+       if ( !rc )
+               CloseHandle( thd );
+       return rc;
+}
+
+int
+ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return )
+{
+       HANDLE thd;
+       int rc = ldap_pvt_thread_pop( thread, &thd );
+
+       if ( !rc ) {
+               DWORD status = WaitForSingleObject( thd, INFINITE );
+               if ( thread_return ) {
+                       DWORD exitcode;
+                       GetExitCodeThread( thd, &exitcode );
+                       *thread_return = (void *)exitcode;
+               }
+               CloseHandle( thd );
+               rc = status == WAIT_FAILED ? -1 : 0;
        }
-       ntids--;
-       return status == WAIT_FAILED ? -1 : 0;
+       return rc;
 }
 
 int 
index 74b561cf0bb368dd47f4337f7d4cfc2defb1f693..87f92aeb910d73653bb1f32940cf1b26c22e8fbf 100644 (file)
@@ -203,6 +203,12 @@ ldap_pvt_thread_exit( void *retval )
        pthread_exit( retval );
 }
 
+int
+ldap_pvt_thread_detach( ldap_pvt_thread_t thread )
+{
+       return ERRVAL( pthread_detach( thread ));
+}
+
 int 
 ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return )
 {
index 6505a5e079b728c938c02b0ee9afe9a92a0fde7f..3efd3778eb8ef3a9c192baaac77ddadefb5e94af 100644 (file)
@@ -52,6 +52,7 @@ ldap_int_thread_initialize( void )
 int
 ldap_int_thread_destroy( void )
 {
+       pth_attr_destroy(joined_attr);
        pth_attr_destroy(detach_attr);
        pth_kill();
        return 0;
@@ -75,6 +76,17 @@ ldap_pvt_thread_exit( void *retval )
        pth_exit( retval );
 }
 
+int
+ldap_pvt_thread_detach( ldap_pvt_thread_t thread )
+{
+       pth_attr_t attr = pth_attr_of( thread );
+       if ( attr ) {
+               pth_attr_set( attr, PTH_ATTR_JOINABLE, FALSE );
+               pth_attr_destroy( attr );
+       }
+       return attr == NULL ? errno : 0;
+}
+
 int ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return )
 {
        return pth_join( thread, thread_return ) ? 0 : errno;
index d60a69f5630b22bf799b1d351155f7b043ba46de..bd91196faef9f132c1cb09bea12442ae0429c23c 100644 (file)
@@ -69,7 +69,17 @@ ldap_pvt_thread_create( ldap_pvt_thread_t * thread,
 void 
 ldap_pvt_thread_exit( void *retval )
 {
-       thr_exit( NULL );
+       thr_exit( retval );
+}
+
+int
+ldap_pvt_thread_detach( ldap_pvt_thread_t thread )
+{
+       /* there is no way to change the detach state of an existing thread
+        * so if it was created joinable, someone must clean it up with
+        * thr_join otherwise its thread ID is leaked.
+        */
+       return 0;
 }
 
 int ldap_pvt_thread_join( ldap_pvt_thread_t thread, void **thread_return )