]> git.sur5r.net Git - openldap/commitdiff
rework timeout strategy a little bit
authorPierangelo Masarati <ando@openldap.org>
Sat, 21 Oct 2006 18:57:27 +0000 (18:57 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sat, 21 Oct 2006 18:57:27 +0000 (18:57 +0000)
include/lutil.h
servers/slapd/back-meta/search.c

index 1fd11221e93996217baf3bdea16fff94cdbe93a3..b4d0108e6b59f8b4437fbd6daa4e7a016dc0fb6e 100644 (file)
@@ -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 */
index d7d251efe176f11b87378cc9dd3908439c440a61..919cb92760d523ca85544ed855c6c3ec52a05b6f 100644 (file)
@@ -28,6 +28,7 @@
 #include <ac/string.h>
 #include <ac/time.h>
 
+#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 ] );