]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/daemon.c
ITS#5328: Make relay_back_has_subordinates() return failure on failure
[openldap] / servers / slapd / daemon.c
index fb01e403f34809d4efff0caad573c4774a25ad88..55681f47124044d5e29832d0cd16ac224f9bf808 100644 (file)
@@ -86,6 +86,8 @@ static ber_socket_t wake_sds[2]
        ;
 static int emfile;
 
+static time_t chk_writetime;
+
 static volatile int waking;
 #ifdef NO_THREADS
 #define WAKE_LISTENER(w)       do { \
@@ -161,9 +163,6 @@ static struct slap_daemon {
 /***************************************
  * Use epoll infrastructure - epoll(4) *
  ***************************************/
-
-#undef SLAP_EVENT_ACK          /* events trigger once per descriptor */
-
 # define SLAP_EVENT_FNAME              "epoll"
 # define SLAP_EVENTS_ARE_INDEXED       0
 # define SLAP_EPOLL_SOCK_IX(s)         (slap_daemon.sd_index[(s)])
@@ -218,7 +217,7 @@ static struct slap_daemon {
        int rc; \
        SLAP_EPOLL_SOCK_IX((s)) = slap_daemon.sd_nfds; \
        SLAP_EPOLL_SOCK_EP((s)).data.ptr = (l) ? (l) : (void *)(&SLAP_EPOLL_SOCK_IX(s)); \
-       SLAP_EPOLL_SOCK_EV((s)) = EPOLLIN|EPOLLET; \
+       SLAP_EPOLL_SOCK_EV((s)) = EPOLLIN; \
        rc = epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_ADD, \
                (s), &SLAP_EPOLL_SOCK_EP((s))); \
        if ( rc == 0 ) { \
@@ -294,12 +293,10 @@ static struct slap_daemon {
 } while (0)
 
 #elif defined(SLAP_X_DEVPOLL) && defined(HAVE_DEVPOLL)
+
 /*************************************************************
  * Use Solaris' (>= 2.7) /dev/poll infrastructure - poll(7d) *
  *************************************************************/
-
-#define SLAP_EVENT_ACK 1       /* events keep signalling unless we stop them */
-
 # define SLAP_EVENT_FNAME              "/dev/poll"
 # define SLAP_EVENTS_ARE_INDEXED       0
 /*
@@ -475,9 +472,6 @@ static struct slap_daemon {
 } while (0)
 
 #else /* ! epoll && ! /dev/poll */
-
-#define SLAP_EVENT_ACK 1       /* events keep signalling unless we stop them */
-
 # ifdef HAVE_WINSOCK
 # define SLAP_EVENT_FNAME              "WSselect"
 /* Winsock provides a "select" function but its fd_sets are
@@ -545,6 +539,7 @@ static struct slap_daemon {
        slap_daemon.sd_flags = (char *)(slapd_ws_sockets + dtblsize); \
        slap_daemon.sd_rflags = slap_daemon.sd_flags + dtblsize; \
        memset( slapd_ws_sockets, -1, dtblsize * sizeof(SOCKET) ); \
+       memset( slap_daemon.sd_flags, 0, dtblsize ); \
        slapd_ws_sockets[0] = wake_sds[0]; \
        slapd_ws_sockets[1] = wake_sds[1]; \
        wake_sds[0] = 0; \
@@ -692,16 +687,16 @@ slapd_slp_init( const char* urls )
        for ( i = 0; slapd_srvurls[i] != NULL; i++ ) {
                if ( strcmp( slapd_srvurls[i], "ldap:///" ) == 0 ) {
                        slapd_srvurls[i] = (char *) ch_realloc( slapd_srvurls[i],
-                               strlen( global_host ) +
+                               global_host_bv.bv_len +
                                sizeof( LDAP_SRVTYPE_PREFIX ) );
                        strcpy( lutil_strcopy(slapd_srvurls[i],
-                               LDAP_SRVTYPE_PREFIX ), global_host );
+                               LDAP_SRVTYPE_PREFIX ), global_host_bv.bv_val );
                } else if ( strcmp( slapd_srvurls[i], "ldaps:///" ) == 0 ) {
                        slapd_srvurls[i] = (char *) ch_realloc( slapd_srvurls[i],
-                               strlen( global_host ) +
+                               global_host_bv.bv_len +
                                sizeof( LDAPS_SRVTYPE_PREFIX ) );
                        strcpy( lutil_strcopy(slapd_srvurls[i],
-                               LDAPS_SRVTYPE_PREFIX ), global_host );
+                               LDAPS_SRVTYPE_PREFIX ), global_host_bv.bv_val );
                }
        }
 
@@ -935,24 +930,6 @@ slapd_remove(
        WAKE_LISTENER(wake || slapd_gentle_shutdown == 2);
 }
 
-void
-slapd_ack_write( ber_socket_t s, int wake )
-{
-#ifdef SLAP_EVENT_ACK
-       ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
-
-       if ( SLAP_SOCK_IS_WRITE( s )) {
-               assert( SLAP_SOCK_IS_ACTIVE( s ));
-
-               SLAP_SOCK_CLR_WRITE( s );
-               slap_daemon.sd_nwriters--;
-       }
-
-       ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
-#endif
-       WAKE_LISTENER(wake);
-}
-
 void
 slapd_clr_write( ber_socket_t s, int wake )
 {
@@ -980,31 +957,14 @@ 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);
 }
 
-int
-slapd_ack_read( ber_socket_t s, int wake )
-{
-#ifdef SLAP_EVENT_ACK
-       int rc = 1;
-       ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
-
-       if ( SLAP_SOCK_IS_ACTIVE( s )) {
-               SLAP_SOCK_CLR_READ( s );
-               rc = 0;
-       }
-       ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
-       if ( !rc )
-               WAKE_LISTENER(wake);
-       return rc;
-#else
-       return 0;
-#endif
-}
-
 int
 slapd_clr_read( ber_socket_t s, int wake )
 {
@@ -1033,6 +993,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 )
 {
@@ -1692,7 +1671,8 @@ slapd_daemon_destroy( void )
 {
        connections_destroy();
 #ifdef HAVE_WINSOCK
-       if ( wake_sds[1] != INVALID_SOCKET && wake_sds[1] != wake_sds[0] )
+       if ( wake_sds[1] != INVALID_SOCKET &&
+               SLAP_FD2SOCK( wake_sds[1] ) != SLAP_FD2SOCK( wake_sds[0] ))
 #endif /* HAVE_WINSOCK */
                tcp_close( SLAP_FD2SOCK(wake_sds[1]) );
 #ifdef HAVE_WINSOCK
@@ -2079,24 +2059,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 );
@@ -2201,14 +2169,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 ) {
@@ -2591,7 +2579,14 @@ slapd_daemon_task(
                                } else if ( !w ) {
                                        Debug( LDAP_DEBUG_CONNS,
                                                "daemon: hangup on %d\n", fd, 0, 0 );
-                                       connection_hangup( fd );
+                                       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 );
+                                       }
                                }
                        }
                }
@@ -2766,6 +2761,8 @@ sockdestroy( void )
 RETSIGTYPE
 slap_sig_shutdown( int sig )
 {
+       int save_errno = errno;
+
 #if 0
        Debug(LDAP_DEBUG_TRACE, "slap_sig_shutdown: signal %d\n", sig, 0, 0);
 #endif
@@ -2794,15 +2791,21 @@ slap_sig_shutdown( int sig )
 
        /* reinstall self */
        (void) SIGNAL_REINSTALL( sig, slap_sig_shutdown );
+
+       errno = save_errno;
 }
 
 RETSIGTYPE
 slap_sig_wake( int sig )
 {
+       int save_errno = errno;
+
        WAKE_LISTENER(1);
 
        /* reinstall self */
        (void) SIGNAL_REINSTALL( sig, slap_sig_wake );
+
+       errno = save_errno;
 }