1 /* thread.c - deal with thread subsystem */
2 /* $OpenLDAP: pkg/ldap/servers/slapd/back-monitor/thread.c,v 1.38.2.7 2008/02/11 23:26:47 kurt Exp $ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2001-2008 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"
45 ldap_pvt_thread_pool_param_t param
;
48 { BER_BVC( "cn=Max" ),
49 BER_BVC("Maximum number of threads as configured"),
50 BER_BVNULL
, LDAP_PVT_THREAD_POOL_PARAM_MAX
, MT_UNKNOWN
},
51 { BER_BVC( "cn=Max Pending" ),
52 BER_BVC("Maximum number of pending threads"),
53 BER_BVNULL
, LDAP_PVT_THREAD_POOL_PARAM_MAX_PENDING
, MT_UNKNOWN
},
54 { BER_BVC( "cn=Open" ),
55 BER_BVC("Number of open threads"),
56 BER_BVNULL
, LDAP_PVT_THREAD_POOL_PARAM_OPEN
, MT_UNKNOWN
},
57 { BER_BVC( "cn=Starting" ),
58 BER_BVC("Number of threads being started"),
59 BER_BVNULL
, LDAP_PVT_THREAD_POOL_PARAM_STARTING
, MT_UNKNOWN
},
60 { BER_BVC( "cn=Active" ),
61 BER_BVC("Number of active threads"),
62 BER_BVNULL
, LDAP_PVT_THREAD_POOL_PARAM_ACTIVE
, MT_UNKNOWN
},
63 { BER_BVC( "cn=Pending" ),
64 BER_BVC("Number of pending threads"),
65 BER_BVNULL
, LDAP_PVT_THREAD_POOL_PARAM_PENDING
, MT_UNKNOWN
},
66 { BER_BVC( "cn=Backload" ),
67 BER_BVC("Number of active plus pending threads"),
68 BER_BVNULL
, LDAP_PVT_THREAD_POOL_PARAM_BACKLOAD
, MT_UNKNOWN
},
69 #if 0 /* not meaningful right now */
70 { BER_BVC( "cn=Active Max" ),
72 BER_BVNULL
, LDAP_PVT_THREAD_POOL_PARAM_ACTIVE_MAX
, MT_UNKNOWN
},
73 { BER_BVC( "cn=Pending Max" ),
75 BER_BVNULL
, LDAP_PVT_THREAD_POOL_PARAM_PENDING_MAX
, MT_UNKNOWN
},
76 { BER_BVC( "cn=Backload Max" ),
78 BER_BVNULL
, LDAP_PVT_THREAD_POOL_PARAM_BACKLOAD_MAX
,MT_UNKNOWN
},
80 { BER_BVC( "cn=State" ),
81 BER_BVC("Thread pool state"),
82 BER_BVNULL
, LDAP_PVT_THREAD_POOL_PARAM_STATE
, MT_UNKNOWN
},
84 { BER_BVC( "cn=Runqueue" ),
85 BER_BVC("Queue of running threads - besides those handling operations"),
86 BER_BVNULL
, LDAP_PVT_THREAD_POOL_PARAM_UNKNOWN
, MT_RUNQUEUE
},
87 { BER_BVC( "cn=Tasklist" ),
88 BER_BVC("List of running plus standby threads - besides those handling operations"),
89 BER_BVNULL
, LDAP_PVT_THREAD_POOL_PARAM_UNKNOWN
, MT_TASKLIST
},
95 monitor_subsys_thread_update(
99 #endif /* ! NO_THREADS */
102 * initializes log subentry
105 monitor_subsys_thread_init(
107 monitor_subsys_t
*ms
)
112 Entry
*e
, **ep
, *e_thread
;
115 ms
->mss_update
= monitor_subsys_thread_update
;
117 mi
= ( monitor_info_t
* )be
->be_private
;
119 if ( monitor_cache_get( mi
, &ms
->mss_ndn
, &e_thread
) ) {
120 Debug( LDAP_DEBUG_ANY
,
121 "monitor_subsys_thread_init: unable to get entry \"%s\"\n",
127 mp
= ( monitor_entry_t
* )e_thread
->e_private
;
128 mp
->mp_children
= NULL
;
129 ep
= &mp
->mp_children
;
131 for ( i
= 0; !BER_BVISNULL( &mt
[ i
].rdn
); i
++ ) {
132 static char buf
[ BACKMONITOR_BUFSIZE
];
135 struct berval bv
= BER_BVNULL
;
140 e
= monitor_entry_stub( &ms
->mss_dn
, &ms
->mss_ndn
,
142 mi
->mi_oc_monitoredObject
, mi
, NULL
, NULL
);
144 Debug( LDAP_DEBUG_ANY
,
145 "monitor_subsys_thread_init: "
146 "unable to create entry \"%s,%s\"\n",
148 ms
->mss_ndn
.bv_val
, 0 );
152 /* NOTE: reference to the normalized DN of the entry,
153 * under the assumption it's not modified */
154 dnRdn( &e
->e_nname
, &mt
[ i
].nrdn
);
156 switch ( mt
[ i
].param
) {
157 case LDAP_PVT_THREAD_POOL_PARAM_UNKNOWN
:
160 case LDAP_PVT_THREAD_POOL_PARAM_STATE
:
161 if ( ldap_pvt_thread_pool_query( &connection_pool
,
162 mt
[ i
].param
, (void *)&state
) == 0 )
164 ber_str2bv( state
, 0, 0, &bv
);
167 BER_BVSTR( &bv
, "unknown" );
172 /* NOTE: in case of error, it'll be set to -1 */
173 (void)ldap_pvt_thread_pool_query( &connection_pool
,
174 mt
[ i
].param
, (void *)&count
);
176 bv
.bv_len
= snprintf( buf
, sizeof( buf
), "%d", count
);
180 if ( !BER_BVISNULL( &bv
) ) {
181 attr_merge_normalize_one( e
, mi
->mi_ad_monitoredInfo
, &bv
, NULL
);
184 if ( !BER_BVISNULL( &mt
[ i
].desc
) ) {
185 attr_merge_normalize_one( e
,
186 slap_schema
.si_ad_description
,
187 &mt
[ i
].desc
, NULL
);
190 mp
= monitor_entrypriv_create();
194 e
->e_private
= ( void * )mp
;
196 mp
->mp_flags
= ms
->mss_flags \
197 | MONITOR_F_SUB
| MONITOR_F_PERSISTENT
;
199 if ( monitor_cache_add( mi
, e
) ) {
200 Debug( LDAP_DEBUG_ANY
,
201 "monitor_subsys_thread_init: "
202 "unable to add entry \"%s,%s\"\n",
204 ms
->mss_dn
.bv_val
, 0 );
212 monitor_cache_release( mi
, e_thread
);
214 #endif /* ! NO_THREADS */
220 monitor_subsys_thread_update(
225 monitor_info_t
*mi
= ( monitor_info_t
* )op
->o_bd
->be_private
;
227 BerVarray vals
= NULL
;
228 char buf
[ BACKMONITOR_BUFSIZE
];
229 struct berval rdn
, bv
;
235 assert( mi
!= NULL
);
237 dnRdn( &e
->e_nname
, &rdn
);
239 for ( i
= 0; !BER_BVISNULL( &mt
[ i
].nrdn
); i
++ ) {
240 if ( dn_match( &mt
[ i
].nrdn
, &rdn
) ) {
246 if ( BER_BVISNULL( &mt
[ which
].nrdn
) ) {
247 return SLAP_CB_CONTINUE
;
250 a
= attr_find( e
->e_attrs
, mi
->mi_ad_monitoredInfo
);
252 switch ( mt
[ which
].param
) {
253 case LDAP_PVT_THREAD_POOL_PARAM_UNKNOWN
:
254 switch ( mt
[ which
].mt
) {
257 if ( a
->a_nvals
!= a
->a_vals
) {
258 ber_bvarray_free( a
->a_nvals
);
260 ber_bvarray_free( a
->a_vals
);
268 ldap_pvt_thread_mutex_lock( &slapd_rq
.rq_mutex
);
269 LDAP_STAILQ_FOREACH( re
, &slapd_rq
.run_list
, rnext
) {
270 bv
.bv_len
= snprintf( buf
, sizeof( buf
), "{%d}%s(%s)",
271 i
, re
->tname
, re
->tspec
);
272 if ( bv
.bv_len
< sizeof( buf
) ) {
273 value_add_one( &vals
, &bv
);
277 ldap_pvt_thread_mutex_unlock( &slapd_rq
.rq_mutex
);
280 attr_merge_normalize( e
, mi
->mi_ad_monitoredInfo
, vals
, NULL
);
281 ber_bvarray_free( vals
);
284 attr_delete( &e
->e_attrs
, mi
->mi_ad_monitoredInfo
);
290 if ( a
->a_nvals
!= a
->a_vals
) {
291 ber_bvarray_free( a
->a_nvals
);
293 ber_bvarray_free( a
->a_vals
);
301 ldap_pvt_thread_mutex_lock( &slapd_rq
.rq_mutex
);
302 LDAP_STAILQ_FOREACH( re
, &slapd_rq
.task_list
, tnext
) {
303 bv
.bv_len
= snprintf( buf
, sizeof( buf
), "{%d}%s(%s)",
304 i
, re
->tname
, re
->tspec
);
305 if ( bv
.bv_len
< sizeof( buf
) ) {
306 value_add_one( &vals
, &bv
);
310 ldap_pvt_thread_mutex_unlock( &slapd_rq
.rq_mutex
);
313 attr_merge_normalize( e
, mi
->mi_ad_monitoredInfo
, vals
, NULL
);
314 ber_bvarray_free( vals
);
317 attr_delete( &e
->e_attrs
, mi
->mi_ad_monitoredInfo
);
326 case LDAP_PVT_THREAD_POOL_PARAM_STATE
:
328 return rs
->sr_err
= LDAP_OTHER
;
330 if ( ldap_pvt_thread_pool_query( &connection_pool
,
331 mt
[ i
].param
, (void *)&state
) == 0 )
333 ber_str2bv( state
, 0, 0, &bv
);
334 ber_bvreplace( &a
->a_vals
[ 0 ], &bv
);
340 return rs
->sr_err
= LDAP_OTHER
;
342 if ( ldap_pvt_thread_pool_query( &connection_pool
,
343 mt
[ i
].param
, (void *)&count
) == 0 )
346 bv
.bv_len
= snprintf( buf
, sizeof( buf
), "%d", count
);
347 if ( bv
.bv_len
< sizeof( buf
) ) {
348 ber_bvreplace( &a
->a_vals
[ 0 ], &bv
);
354 /* FIXME: touch modifyTimestamp? */
356 return SLAP_CB_CONTINUE
;
358 #endif /* ! NO_THREADS */