X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fdaemon.c;h=f9606c928e899aaad03615bf7b88e3f3e1227aa7;hb=6044e46ec7af21658829edde47c4c9c904093df3;hp=45bd7d3fe801afd8a33cad32a46c09c51e1793c4;hpb=9d787d8d42eba8ff61842f4b49f8afcabf38bb78;p=openldap diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c index 45bd7d3fe8..f9606c928e 100644 --- a/servers/slapd/daemon.c +++ b/servers/slapd/daemon.c @@ -1,7 +1,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 1998-2008 The OpenLDAP Foundation. + * Copyright 1998-2009 The OpenLDAP Foundation. * Portions Copyright 2007 by Howard Chu, Symas Corporation. * All rights reserved. * @@ -79,9 +79,15 @@ Listener **slap_listeners = NULL; #define SLAPD_LISTEN_BACKLOG 1024 #endif /* ! SLAPD_LISTEN_BACKLOG */ -static ber_socket_t wake_sds[2]; +static ber_socket_t wake_sds[2] +#ifdef HAVE_WINSOCK + = { INVALID_SOCKET, INVALID_SOCKET } +#endif /* HAVE_WINSOCK */ + ; static int emfile; +static time_t chk_writetime; + static volatile int waking; #ifdef NO_THREADS #define WAKE_LISTENER(w) do { \ @@ -950,6 +956,9 @@ slapd_set_write( ber_socket_t s, int wake ) SLAP_SOCK_SET_WRITE( s ); slap_daemon.sd_nwriters++; } + if (( wake & 2 ) && global_writetimeout ) { + chk_writetime = slap_get_time(); + } ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex ); WAKE_LISTENER(wake); @@ -983,6 +992,25 @@ slapd_set_read( ber_socket_t s, int wake ) WAKE_LISTENER(wake); } +time_t +slapd_get_writetime() +{ + time_t cur; + ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex ); + cur = chk_writetime; + ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex ); + return cur; +} + +void +slapd_clr_writetime( time_t old ) +{ + ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex ); + if ( chk_writetime == old ) + chk_writetime = 0; + ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex ); +} + static void slapd_close( ber_socket_t s ) { @@ -1641,8 +1669,14 @@ int slapd_daemon_destroy( void ) { connections_destroy(); - tcp_close( SLAP_FD2SOCK(wake_sds[1]) ); - tcp_close( SLAP_FD2SOCK(wake_sds[0]) ); +#ifdef HAVE_WINSOCK + if ( wake_sds[1] != INVALID_SOCKET && wake_sds[1] != wake_sds[0] ) +#endif /* HAVE_WINSOCK */ + tcp_close( SLAP_FD2SOCK(wake_sds[1]) ); +#ifdef HAVE_WINSOCK + if ( wake_sds[0] != INVALID_SOCKET ) +#endif /* HAVE_WINSOCK */ + tcp_close( SLAP_FD2SOCK(wake_sds[0]) ); sockdestroy(); #ifdef HAVE_SLP @@ -2023,24 +2057,12 @@ slapd_daemon_task( { int l; time_t last_idle_check = 0; - struct timeval idle; int ebadf = 0; #define SLAPD_IDLE_CHECK_LIMIT 4 if ( global_idletimeout > 0 ) { last_idle_check = slap_get_time(); - /* Set the select timeout. - * Don't just truncate, preserve the fractions of - * seconds to prevent sleeping for zero time. - */ - idle.tv_sec = global_idletimeout / SLAPD_IDLE_CHECK_LIMIT; - idle.tv_usec = global_idletimeout - \ - ( idle.tv_sec * SLAPD_IDLE_CHECK_LIMIT ); - idle.tv_usec *= 1000000 / SLAPD_IDLE_CHECK_LIMIT; - } else { - idle.tv_sec = 0; - idle.tv_usec = 0; } slapd_add( wake_sds[0], 0, NULL ); @@ -2145,14 +2167,34 @@ slapd_daemon_task( now = slap_get_time(); - if ( ( global_idletimeout > 0 ) && - difftime( last_idle_check + - global_idletimeout/SLAPD_IDLE_CHECK_LIMIT, now ) < 0 ) - { - connections_timeout_idle( now ); - last_idle_check = now; + if ( global_idletimeout > 0 || chk_writetime ) { + int check = 0; + /* Set the select timeout. + * Don't just truncate, preserve the fractions of + * seconds to prevent sleeping for zero time. + */ + if ( chk_writetime ) { + tv.tv_sec = global_writetimeout; + tv.tv_usec = global_writetimeout; + if ( difftime( chk_writetime, now ) < 0 ) + check = 2; + } else { + tv.tv_sec = global_idletimeout / SLAPD_IDLE_CHECK_LIMIT; + tv.tv_usec = global_idletimeout - \ + ( tv.tv_sec * SLAPD_IDLE_CHECK_LIMIT ); + tv.tv_usec *= 1000000 / SLAPD_IDLE_CHECK_LIMIT; + if ( difftime( last_idle_check + + global_idletimeout/SLAPD_IDLE_CHECK_LIMIT, now ) < 0 ) + check = 1; + } + if ( check ) { + connections_timeout_idle( now ); + last_idle_check = now; + } + } else { + tv.tv_sec = 0; + tv.tv_usec = 0; } - tv = idle; #ifdef SIGHUP if ( slapd_gentle_shutdown ) { @@ -2291,7 +2333,7 @@ slapd_daemon_task( Debug( LDAP_DEBUG_ANY, "daemon: " SLAP_EVENT_FNAME - "failed count %d " + " failed count %d " "err (%d): %s\n", ebadf, err, sock_errstr( err ) ); @@ -2485,7 +2527,7 @@ slapd_daemon_task( #endif /* LDAP_DEBUG */ for ( i = 0; i < ns; i++ ) { - int rc = 1, fd; + int rc = 1, fd, w = 0; if ( SLAP_EVENT_IS_LISTENER( i ) ) { rc = slap_listener_activate( SLAP_EVENT_LISTENER( i ) ); @@ -2503,7 +2545,7 @@ slapd_daemon_task( char c[BUFSIZ]; waking = 0; tcp_read( SLAP_FD2SOCK(wake_sds[0]), c, sizeof(c) ); - break; + continue; } if ( SLAP_EVENT_IS_WRITE( i ) ) { @@ -2512,6 +2554,7 @@ slapd_daemon_task( fd, 0, 0 ); SLAP_EVENT_CLR_WRITE( i ); + w = 1; /* * NOTE: it is possible that the connection was closed @@ -2531,9 +2574,17 @@ slapd_daemon_task( SLAP_EVENT_CLR_READ( i ); connection_read_activate( fd ); - } else { + } else if ( !w ) { Debug( LDAP_DEBUG_CONNS, "daemon: hangup on %d\n", fd, 0, 0 ); + if ( SLAP_SOCK_IS_ACTIVE( fd )) { +#ifdef HAVE_EPOLL + /* Don't keep reporting the hangup + */ + SLAP_EPOLL_SOCK_SET( fd, EPOLLET ); +#endif + connection_hangup( fd ); + } } } } @@ -2572,9 +2623,12 @@ slapd_daemon_task( connections_shutdown(); } - Debug( LDAP_DEBUG_ANY, - "slapd shutdown: waiting for %d threads to terminate\n", - ldap_pvt_thread_pool_backload( &connection_pool ), 0, 0 ); + if ( LogTest( LDAP_DEBUG_ANY )) { + int t = ldap_pvt_thread_pool_backload( &connection_pool ); + Debug( LDAP_DEBUG_ANY, + "slapd shutdown: waiting for %d operations/tasks to finish\n", + t, 0, 0 ); + } ldap_pvt_thread_pool_destroy( &connection_pool, 1 ); free( slap_listeners );