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"
33 monitor_subsys_thread_update(
49 ldap_pvt_thread_pool_param_t param;
52 { BER_BVC( "cn=Max" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_MAX, MT_UNKNOWN },
53 { BER_BVC( "cn=Max Pending" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_MAX_PENDING, MT_UNKNOWN },
54 { BER_BVC( "cn=Open" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_OPEN, MT_UNKNOWN },
55 { BER_BVC( "cn=Starting" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_STARTING, MT_UNKNOWN },
56 { BER_BVC( "cn=Active" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_ACTIVE, MT_UNKNOWN },
57 { BER_BVC( "cn=Pending" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_PENDING, MT_UNKNOWN },
58 { BER_BVC( "cn=Backload" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_BACKLOAD, MT_UNKNOWN },
59 #if 0 /* not meaningful right now */
60 { BER_BVC( "cn=Active Max" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_ACTIVE_MAX, MT_UNKNOWN },
61 { BER_BVC( "cn=Pending Max" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_PENDING_MAX, MT_UNKNOWN },
62 { BER_BVC( "cn=Backload Max" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_BACKLOAD_MAX,MT_UNKNOWN },
64 { BER_BVC( "cn=State" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_STATE, MT_UNKNOWN },
66 { BER_BVC( "cn=Runqueue" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_UNKNOWN, MT_RUNQUEUE },
67 { BER_BVC( "cn=Tasklist" ), BER_BVNULL, LDAP_PVT_THREAD_POOL_PARAM_UNKNOWN, MT_TASKLIST },
73 * initializes log subentry
76 monitor_subsys_thread_init(
83 Entry *e, **ep, *e_thread;
86 ms->mss_update = monitor_subsys_thread_update;
88 mi = ( monitor_info_t * )be->be_private;
90 if ( monitor_cache_get( mi, &ms->mss_ndn, &e_thread ) ) {
91 Debug( LDAP_DEBUG_ANY,
92 "monitor_subsys_thread_init: unable to get entry \"%s\"\n",
98 mp = ( monitor_entry_t * )e_thread->e_private;
99 mp->mp_children = NULL;
100 ep = &mp->mp_children;
102 for ( i = 0; !BER_BVISNULL( &mt[ i ].rdn ); i++ ) {
103 static char buf[ BACKMONITOR_BUFSIZE ];
106 struct berval bv = BER_BVNULL;
111 e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn,
113 mi->mi_oc_monitoredObject, mi, NULL, NULL );
115 Debug( LDAP_DEBUG_ANY,
116 "monitor_subsys_thread_init: "
117 "unable to create entry \"%s,%s\"\n",
119 ms->mss_ndn.bv_val, 0 );
123 /* NOTE: reference to the normalized DN of the entry,
124 * under the assumption it's not modified */
125 dnRdn( &e->e_nname, &mt[ i ].nrdn );
127 switch ( mt[ i ].param ) {
128 case LDAP_PVT_THREAD_POOL_PARAM_UNKNOWN:
131 case LDAP_PVT_THREAD_POOL_PARAM_STATE:
132 ldap_pvt_thread_pool_query( &connection_pool,
133 mt[ i ].param, (void *)&state );
134 ber_str2bv( state, 0, 0, &bv );
138 ldap_pvt_thread_pool_query( &connection_pool,
139 mt[ i ].param, (void *)&count );
141 bv.bv_len = snprintf( buf, sizeof( buf ), "%d", count );
145 if ( !BER_BVISNULL( &bv ) ) {
146 attr_merge_normalize_one( e, mi->mi_ad_monitoredInfo, &bv, NULL );
149 mp = monitor_entrypriv_create();
153 e->e_private = ( void * )mp;
155 mp->mp_flags = ms->mss_flags \
156 | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
158 if ( monitor_cache_add( mi, e ) ) {
159 Debug( LDAP_DEBUG_ANY,
160 "monitor_subsys_thread_init: "
161 "unable to add entry \"%s,%s\"\n",
163 ms->mss_ndn.bv_val, 0 );
171 monitor_cache_release( mi, e_thread );
177 monitor_subsys_thread_update(
182 monitor_info_t *mi = ( monitor_info_t * )op->o_bd->be_private;
184 BerVarray vals = NULL;
185 char buf[ BACKMONITOR_BUFSIZE ];
186 struct berval rdn, bv;
192 assert( mi != NULL );
194 dnRdn( &e->e_nname, &rdn );
196 for ( i = 0; !BER_BVISNULL( &mt[ i ].nrdn ); i++ ) {
197 if ( dn_match( &mt[ i ].nrdn, &rdn ) ) {
203 if ( BER_BVISNULL( &mt[ which ].nrdn ) ) {
204 return SLAP_CB_CONTINUE;
207 a = attr_find( e->e_attrs, mi->mi_ad_monitoredInfo );
209 switch ( mt[ which ].param ) {
210 case LDAP_PVT_THREAD_POOL_PARAM_UNKNOWN:
211 switch ( mt[ which ].mt ) {
214 if ( a->a_nvals != a->a_vals ) {
215 ber_bvarray_free( a->a_nvals );
217 ber_bvarray_free( a->a_vals );
224 ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
225 LDAP_STAILQ_FOREACH( re, &slapd_rq.run_list, rnext ) {
226 bv.bv_len = snprintf( buf, sizeof( buf ), "{%d}%s(%s)",
227 i, re->tname, re->tspec );
228 if ( bv.bv_len < sizeof( buf ) ) {
229 value_add_one( &vals, &bv );
233 ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
236 attr_merge_normalize( e, mi->mi_ad_monitoredInfo, vals, NULL );
237 ber_bvarray_free( vals );
243 if ( a->a_nvals != a->a_vals ) {
244 ber_bvarray_free( a->a_nvals );
246 ber_bvarray_free( a->a_vals );
253 ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
254 LDAP_STAILQ_FOREACH( re, &slapd_rq.task_list, tnext ) {
255 bv.bv_len = snprintf( buf, sizeof( buf ), "{%d}%s(%s)",
256 i, re->tname, re->tspec );
257 if ( bv.bv_len < sizeof( buf ) ) {
258 value_add_one( &vals, &bv );
262 ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
265 attr_merge_normalize( e, mi->mi_ad_monitoredInfo, vals, NULL );
266 ber_bvarray_free( vals );
275 case LDAP_PVT_THREAD_POOL_PARAM_STATE:
277 return rs->sr_err = LDAP_OTHER;
279 ldap_pvt_thread_pool_query( &connection_pool,
280 mt[ i ].param, (void *)&state );
281 ber_str2bv( state, 0, 0, &bv );
282 ber_bvreplace( &a->a_vals[ 0 ], &bv );
287 return rs->sr_err = LDAP_OTHER;
289 ldap_pvt_thread_pool_query( &connection_pool,
290 mt[ i ].param, (void *)&count );
292 bv.bv_len = snprintf( buf, sizeof( buf ), "%d", count );
293 if ( bv.bv_len >= sizeof( buf ) ) {
297 ber_bvreplace( &a->a_vals[ 0 ], &bv );
301 /* FIXME: touch modifyTimestamp? */
303 return SLAP_CB_CONTINUE;