mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-06-09 00:32:08 -04:00
ITS#8901 ldap_pvt_thread: add _detach() support
Prep for fixups to tpool.
This commit is contained in:
parent
6d50a5730a
commit
23c07757b2
8 changed files with 123 additions and 20 deletions
|
|
@ -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 ));
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -112,7 +113,7 @@
|
|||
#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
|
||||
|
|
@ -148,6 +149,7 @@
|
|||
#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
|
||||
|
|
@ -178,7 +180,7 @@
|
|||
#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
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
status = WaitForSingleObject( tids[i].thd, INFINITE );
|
||||
for (; i<ntids; i++) {
|
||||
tids[i] = tids[i+1];
|
||||
if ( i<ntids ) {
|
||||
*thd = tids[i].thd;
|
||||
for (; i<ntids; i++) {
|
||||
tids[i] = tids[i+1];
|
||||
}
|
||||
ntids--;
|
||||
rc = 0;
|
||||
}
|
||||
ntids--;
|
||||
return status == WAIT_FAILED ? -1 : 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 );
|
||||
|
||||
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;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
Loading…
Reference in a new issue