From 0aebe8af08480beaeefb93545ecdbe033db20923 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Sat, 21 Oct 2006 18:57:27 +0000 Subject: [PATCH] rework timeout strategy a little bit --- include/lutil.h | 26 ++++++++++++++++++++++++++ servers/slapd/back-meta/search.c | 29 +++++++++++++++++++---------- 2 files changed, 45 insertions(+), 10 deletions(-) diff --git a/include/lutil.h b/include/lutil.h index 1fd11221e9..b4d0108e6b 100644 --- a/include/lutil.h +++ b/include/lutil.h @@ -296,6 +296,32 @@ lutil_parse_time( const char *in, unsigned long *tp ); LDAP_LUTIL_F (int) lutil_unparse_time( char *buf, size_t buflen, unsigned long t ); +#ifdef timerdiv +#define lutil_timerdiv timerdiv +#else /* ! timerdiv */ +/* works inplace (x == t) */ +#define lutil_timerdiv(t,d,x) \ + do { \ + time_t s = (t)->tv_sec; \ + assert( d > 0 ); \ + (x)->tv_sec = s / d; \ + (x)->tv_usec = ( (t)->tv_usec + 1000000 * ( s % d ) ) / d; \ + } while ( 0 ) +#endif /* ! timerdiv */ + +#ifdef timermul +#define lutil_timermul timermul +#else /* ! timermul */ +/* works inplace (x == t) */ +#define lutil_timermul(t,m,x) \ + do { \ + time_t u = (t)->tv_usec * m; \ + assert( m > 0 ); \ + (x)->tv_sec = (t)->tv_sec * m + u / 1000000; \ + (x)->tv_usec = u % 1000000; \ + } while ( 0 ); +#endif /* ! timermul */ + LDAP_END_DECL #endif /* _LUTIL_H */ diff --git a/servers/slapd/back-meta/search.c b/servers/slapd/back-meta/search.c index d7d251efe1..919cb92760 100644 --- a/servers/slapd/back-meta/search.c +++ b/servers/slapd/back-meta/search.c @@ -28,6 +28,7 @@ #include #include +#include "lutil.h" #include "slap.h" #include "../back-ldap/back-ldap.h" #include "back-meta.h" @@ -529,7 +530,8 @@ meta_back_search( Operation *op, SlapReply *rs ) { metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private; metaconn_t *mc; - struct timeval tv = { 0, 0 }; + struct timeval save_tv = { 0, 0 }, + tv; time_t stoptime = (time_t)-1; int rc = 0, sres = LDAP_SUCCESS; char *matched = NULL; @@ -771,6 +773,7 @@ meta_back_search( Operation *op, SlapReply *rs ) * get a LDAP_TIMELIMIT_EXCEEDED from * one of them ... */ + tv = save_tv; rc = ldap_result( msc->msc_ld, candidates[ i ].sr_msgid, LDAP_MSG_RECEIVED, &tv, &res ); switch ( rc ) { @@ -883,8 +886,8 @@ really_bad:; /* don't wait any longer... */ gotit = 1; - tv.tv_sec = 0; - tv.tv_usec = 0; + save_tv.tv_sec = 0; + save_tv.tv_usec = 0; } else if ( rc == LDAP_RES_SEARCH_REFERENCE ) { char **references = NULL; @@ -1204,11 +1207,18 @@ really_bad:; /* if no entry was found during this loop, * set a minimal timeout */ - if ( gotit == 0 ) { - /* make the entire wait last - * LDAP_BACK_RESULT_UTIMEOUT at worst */ - tv.tv_sec = 0; - tv.tv_usec = LDAP_BACK_RESULT_UTIMEOUT/initial_candidates; + if ( ncandidates > 0 && gotit == 0 ) { + if ( save_tv.tv_sec == 0 && save_tv.tv_usec == 0 ) { + save_tv.tv_usec = LDAP_BACK_RESULT_UTIMEOUT/initial_candidates; + + /* arbitrarily limit to something between 1 and 2 minutes */ + } else if ( ( stoptime == -1 && save_tv.tv_sec < 60 ) + || save_tv.tv_sec < ( stoptime - slap_get_time() ) / ( 2 * ncandidates ) ) + { + /* double the timeout */ + lutil_timermul( &save_tv, 2, &save_tv ); + } + ldap_pvt_thread_yield(); } } @@ -1351,14 +1361,13 @@ finish:; if ( mc && META_IS_BINDING( &candidates[ i ] ) ) { ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); if ( LDAP_BACK_CONN_BINDING( &mc->mc_conns[ i ] ) ) { - LDAP_BACK_CONN_BINDING_CLEAR( &mc->mc_conns[ i ] ); - assert( candidates[ i ].sr_msgid >= 0 ); assert( mc->mc_conns[ i ].msc_ld != NULL ); /* if still binding, destroy */ ldap_unbind_ext( mc->mc_conns[ i ].msc_ld, NULL, NULL ); mc->mc_conns[ i ].msc_ld = NULL; + LDAP_BACK_CONN_BINDING_CLEAR( &mc->mc_conns[ i ] ); } ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); META_BINDING_CLEAR( &candidates[ i ] ); -- 2.39.5