1 /* thread.c - deal with thread subsystem */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2001-2006 The OpenLDAP Foundation.
6 * Portions Copyright 2001-2003 Pierangelo Masarati.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
13 * A copy of this license is available in file LICENSE in the
14 * top-level directory of the distribution or, alternatively, at
15 * <http://www.OpenLDAP.org/license.html>.
18 * This work was initially developed by Pierangelo Masarati for inclusion
19 * in OpenLDAP Software.
25 #include <ac/string.h>
28 #include "back-monitor.h"
44 ldap_pvt_thread_pool_param_t param;
47 { BER_BVC( "cn=Max" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_MAX, MT_UNKNOWN },
48 { BER_BVC( "cn=Max Pending" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_MAX_PENDING, MT_UNKNOWN },
49 { BER_BVC( "cn=Open" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_OPEN, MT_UNKNOWN },
50 { BER_BVC( "cn=Starting" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_STARTING, MT_UNKNOWN },
51 { BER_BVC( "cn=Active" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_ACTIVE, MT_UNKNOWN },
52 { BER_BVC( "cn=Pending" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_PENDING, MT_UNKNOWN },
53 { BER_BVC( "cn=Backload" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_BACKLOAD, MT_UNKNOWN },
54 #if 0 /* not meaningful right now */
55 { BER_BVC( "cn=Active Max" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_ACTIVE_MAX, MT_UNKNOWN },
56 { BER_BVC( "cn=Pending Max" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_PENDING_MAX, MT_UNKNOWN },
57 { BER_BVC( "cn=Backload Max" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_BACKLOAD_MAX,MT_UNKNOWN },
59 { BER_BVC( "cn=State" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_STATE, MT_UNKNOWN },
61 { BER_BVC( "cn=Runqueue" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_UNKNOWN, MT_RUNQUEUE },
62 { BER_BVC( "cn=Tasklist" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_UNKNOWN, MT_TASKLIST },
68 monitor_subsys_thread_update(
72 #endif /* ! NO_THREADS */
75 * initializes log subentry
78 monitor_subsys_thread_init(
80 monitor_subsys_t *ms )
85 Entry *e, **ep, *e_thread;
88 ms->mss_update = monitor_subsys_thread_update;
90 mi = ( monitor_info_t * )be->be_private;
92 if ( monitor_cache_get( mi, &ms->mss_ndn, &e_thread ) ) {
93 Debug( LDAP_DEBUG_ANY,
94 "monitor_subsys_thread_init: unable to get entry \"%s\"\n",
100 mp = ( monitor_entry_t * )e_thread->e_private;
101 mp->mp_children = NULL;
102 ep = &mp->mp_children;
104 for ( i = 0; !BER_BVISNULL( &mt[ i ].rdn ); i++ ) {
105 static char buf[ BACKMONITOR_BUFSIZE ];
108 struct berval bv = BER_BVNULL;
113 e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn,
115 mi->mi_oc_monitoredObject, mi, NULL, NULL );
117 Debug( LDAP_DEBUG_ANY,
118 "monitor_subsys_thread_init: "
119 "unable to create entry \"%s,%s\"\n",
121 ms->mss_ndn.bv_val, 0 );
125 /* NOTE: reference to the normalized DN of the entry,
126 * under the assumption it's not modified */
127 dnRdn( &e->e_nname, &mt[ i ].nrdn );
129 switch ( mt[ i ].param ) {
130 case LDAP_PVT_THREAD_POOL_PARAM_UNKNOWN:
133 case LDAP_PVT_THREAD_POOL_PARAM_STATE:
134 if ( ldap_pvt_thread_pool_query( &connection_pool,
135 mt[ i ].param, (void *)&state ) == 0 )
137 ber_str2bv( state, 0, 0, &bv );
140 BER_BVSTR( &bv, "unknown" );
145 /* NOTE: in case of error, it'll be set to -1 */
146 (void)ldap_pvt_thread_pool_query( &connection_pool,
147 mt[ i ].param, (void *)&count );
149 bv.bv_len = snprintf( buf, sizeof( buf ), "%d", count );
153 if ( !BER_BVISNULL( &bv ) ) {
154 attr_merge_normalize_one( e, mi->mi_ad_monitoredInfo, &bv, NULL );
157 mp = monitor_entrypriv_create();
161 e->e_private = ( void * )mp;
163 mp->mp_flags = ms->mss_flags \
164 | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
166 if ( monitor_cache_add( mi, e ) ) {
167 Debug( LDAP_DEBUG_ANY,
168 "monitor_subsys_thread_init: "
169 "unable to add entry \"%s,%s\"\n",
171 ms->mss_ndn.bv_val, 0 );
179 monitor_cache_release( mi, e_thread );
181 #endif /* ! NO_THREADS */
187 monitor_subsys_thread_update(
192 monitor_info_t *mi = ( monitor_info_t * )op->o_bd->be_private;
194 BerVarray vals = NULL;
195 char buf[ BACKMONITOR_BUFSIZE ];
196 struct berval rdn, bv;
202 assert( mi != NULL );
204 dnRdn( &e->e_nname, &rdn );
206 for ( i = 0; !BER_BVISNULL( &mt[ i ].nrdn ); i++ ) {
207 if ( dn_match( &mt[ i ].nrdn, &rdn ) ) {
213 if ( BER_BVISNULL( &mt[ which ].nrdn ) ) {
214 return SLAP_CB_CONTINUE;
217 a = attr_find( e->e_attrs, mi->mi_ad_monitoredInfo );
219 switch ( mt[ which ].param ) {
220 case LDAP_PVT_THREAD_POOL_PARAM_UNKNOWN:
221 switch ( mt[ which ].mt ) {
224 if ( a->a_nvals != a->a_vals ) {
225 ber_bvarray_free( a->a_nvals );
227 ber_bvarray_free( a->a_vals );
234 ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
235 LDAP_STAILQ_FOREACH( re, &slapd_rq.run_list, rnext ) {
236 bv.bv_len = snprintf( buf, sizeof( buf ), "{%d}%s(%s)",
237 i, re->tname, re->tspec );
238 if ( bv.bv_len < sizeof( buf ) ) {
239 value_add_one( &vals, &bv );
243 ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
246 attr_merge_normalize( e, mi->mi_ad_monitoredInfo, vals, NULL );
247 ber_bvarray_free( vals );
253 if ( a->a_nvals != a->a_vals ) {
254 ber_bvarray_free( a->a_nvals );
256 ber_bvarray_free( a->a_vals );
263 ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
264 LDAP_STAILQ_FOREACH( re, &slapd_rq.task_list, tnext ) {
265 bv.bv_len = snprintf( buf, sizeof( buf ), "{%d}%s(%s)",
266 i, re->tname, re->tspec );
267 if ( bv.bv_len < sizeof( buf ) ) {
268 value_add_one( &vals, &bv );
272 ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
275 attr_merge_normalize( e, mi->mi_ad_monitoredInfo, vals, NULL );
276 ber_bvarray_free( vals );
285 case LDAP_PVT_THREAD_POOL_PARAM_STATE:
287 return rs->sr_err = LDAP_OTHER;
289 if ( ldap_pvt_thread_pool_query( &connection_pool,
290 mt[ i ].param, (void *)&state ) == 0 )
292 ber_str2bv( state, 0, 0, &bv );
293 ber_bvreplace( &a->a_vals[ 0 ], &bv );
299 return rs->sr_err = LDAP_OTHER;
301 if ( ldap_pvt_thread_pool_query( &connection_pool,
302 mt[ i ].param, (void *)&count ) == 0 )
305 bv.bv_len = snprintf( buf, sizeof( buf ), "%d", count );
306 if ( bv.bv_len < sizeof( buf ) ) {
307 ber_bvreplace( &a->a_vals[ 0 ], &bv );
313 /* FIXME: touch modifyTimestamp? */
315 return SLAP_CB_CONTINUE;
317 #endif /* ! NO_THREADS */