X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fdaemon.c;h=e6b5e157cb15da24fc61717b9c864d0980152b31;hb=543c588772b22a029b60e72e45e68032935ecd54;hp=aad84bea5d82a5b701f5db1b0033c78aff286d51;hpb=e21bba89dbec62625e1f7090c9a5b6e5f219e46b;p=openldap diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c index aad84bea5d..e6b5e157cb 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-2005 The OpenLDAP Foundation. + * Copyright 1998-2006 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -81,10 +81,9 @@ Listener **slap_listeners = NULL; static ber_socket_t wake_sds[2]; static int emfile; -static int waking; +static volatile int waking; #define WAKE_LISTENER(w) do { \ - if ((w) && waking < 5) { \ - waking++; \ + if ((w) && ++waking < 5) { \ tcp_write( wake_sds[1], "0", 1 ); \ } \ } while(0) @@ -95,6 +94,9 @@ volatile sig_atomic_t slapd_abrupt_shutdown = 0; static struct slap_daemon { ldap_pvt_thread_mutex_t sd_mutex; +#ifdef HAVE_TCPD + ldap_pvt_thread_mutex_t tcpd_mutex; +#endif ber_socket_t sd_nactives; int sd_nwriters; @@ -105,10 +107,6 @@ static struct slap_daemon { int *sd_index; int sd_epfd; int sd_nfds; -# ifdef SLAP_LIGHTWEIGHT_LISTENER - int *sd_suspend; /* 0: suspended, 1: not suspended */ -# endif - #else #ifndef HAVE_WINSOCK /* In winsock, accept() returns values higher than dtblsize @@ -118,9 +116,6 @@ static struct slap_daemon { fd_set sd_actives; fd_set sd_readers; fd_set sd_writers; -# ifdef SLAP_LIGHTWEIGHT_LISTENER - fd_set sd_suspend; /* unset: suspended, set: not suspended */ -# endif #endif } slap_daemon; @@ -155,7 +150,7 @@ static struct slap_daemon { # define SLAP_SOCK_SET_READ(s) SLAP_SET_SOCK(s, EPOLLIN) # define SLAP_SOCK_SET_WRITE(s) SLAP_SET_SOCK(s, EPOLLOUT) -# ifdef SLAP_LIGHTWEIGHT_LISTENER +# ifdef SLAP_LIGHTWEIGHT_DISPATCHER # define SLAP_SOCK_SET_SUSPEND(s) \ ( slap_daemon.sd_suspend[SLAP_SOCK_IX(s)] = 1 ) # define SLAP_SOCK_CLR_SUSPEND(s) \ @@ -187,8 +182,8 @@ static struct slap_daemon { slap_daemon.sd_nfds++; \ } else { \ Debug( LDAP_DEBUG_ANY, \ - "daemon: epoll_ctl ADD failed, errno %d, shutting down\n", \ - errno, 0, 0 ); \ + "daemon: epoll_ctl(ADD,fd=%d) failed, errno=%d, shutting down\n", \ + s, errno, 0 ); \ slapd_shutdown = 2; \ } \ } while (0) @@ -199,24 +194,9 @@ static struct slap_daemon { # define SLAP_EV_PTRFD(ptr) (SLAP_EV_LISTENER(ptr) ? \ ((Listener *)ptr)->sl_sd : (int *)(ptr) - slap_daemon.sd_index) -# ifdef SLAP_LIGHTWEIGHT_LISTENER -# define SLAP_DEL_SOCK(s) do { \ - int fd, rc, suspend, index = SLAP_SOCK_IX((s)); \ - rc = epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_DEL, \ - (s), &SLAP_SOCK_EP((s))); \ - slap_daemon.sd_epolls[index] = \ - slap_daemon.sd_epolls[slap_daemon.sd_nfds-1]; \ - fd = SLAP_EV_PTRFD(slap_daemon.sd_epolls[index].data.ptr); \ - slap_daemon.sd_suspend[index] = \ - slap_daemon.sd_suspend[slap_daemon.sd_nfds-1]; \ - slap_daemon.sd_suspend[slap_daemon.sd_nfds-1] = 0; \ - slap_daemon.sd_index[fd] = index; \ - slap_daemon.sd_index[(s)] = -1; \ - slap_daemon.sd_nfds--; \ -} while (0) -# else -# define SLAP_DEL_SOCK(s) do { \ +# define SLAP_DEL_SOCK(s) do { \ int fd, rc, index = SLAP_SOCK_IX((s)); \ + if ( index < 0 ) break; \ rc = epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_DEL, \ (s), &SLAP_SOCK_EP((s))); \ slap_daemon.sd_epolls[index] = \ @@ -226,7 +206,6 @@ static struct slap_daemon { slap_daemon.sd_index[(s)] = -1; \ slap_daemon.sd_nfds--; \ } while (0) -# endif # define SLAP_EVENT_CLR_READ(i) SLAP_CLR_EVENT((i), EPOLLIN) # define SLAP_EVENT_CLR_WRITE(i) SLAP_CLR_EVENT((i), EPOLLOUT) @@ -236,32 +215,17 @@ static struct slap_daemon { # define SLAP_EVENT_IS_READ(i) SLAP_CHK_EVENT((i), EPOLLIN) # define SLAP_EVENT_IS_WRITE(i) SLAP_CHK_EVENT((i), EPOLLOUT) # define SLAP_EVENT_IS_LISTENER(i) SLAP_EV_LISTENER(revents[(i)].data.ptr) -# define SLAP_EVENT_LISTENER(i) (revents[(i)].data.ptr) +# define SLAP_EVENT_LISTENER(i) ((Listener *)(revents[(i)].data.ptr)) # define SLAP_EVENT_FD(i) SLAP_EV_PTRFD(revents[(i)].data.ptr) -# define SLAP_SOCK_SET_MUTE(s) SLAP_SOCK_CLR_READ((s)) -# define SLAP_SOCK_CLR_MUTE(s) SLAP_SOCK_SET_READ((s)) -# define SLAP_SOCK_IS_MUTE(s) (!SLAP_SOCK_IS_READ((s))) - -# ifdef SLAP_LIGHTWEIGHT_LISTENER -# define SLAP_SOCK_SET_INIT do { \ - slap_daemon.sd_epolls = \ - ch_malloc( sizeof(struct epoll_event) * dtblsize * 2 ); \ - slap_daemon.sd_index = ch_malloc(sizeof(int) * dtblsize); \ - slap_daemon.sd_epfd = epoll_create( dtblsize ); \ - for (i=0; i 0 ? &writefds : NULL, NULL, (tvp) ) - -# define SLAP_SOCK_SET_MUTE(s) FD_CLR((s), &readfds) -# define SLAP_SOCK_CLR_MUTE(s) FD_SET((s), &readfds) -# define SLAP_SOCK_IS_MUTE(s) (!FD_ISSET((s), &readfds)) #endif #ifdef HAVE_SLP @@ -504,36 +449,52 @@ static void slapd_add(ber_socket_t s, int isactive, Listener *sl) { ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex ); -#ifdef SLAP_LIGHTWEIGHT_LISTENER +#ifdef SLAP_LIGHTWEIGHT_DISPATCHER WAKE_LISTENER(1); #endif } +void slapd_sd_lock() +{ + ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex ); +} + +void slapd_sd_unlock() +{ + ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex ); +} + /* * Remove the descriptor from daemon control */ void slapd_remove( ber_socket_t s, int wasactive, - int wake ) + int wake, + int locked ) { int waswriter; + int wasreader; - ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex ); + if ( !locked ) + ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex ); + + assert( SLAP_SOCK_IS_ACTIVE( s )); if ( wasactive ) slap_daemon.sd_nactives--; waswriter = SLAP_SOCK_IS_WRITE(s); + wasreader = SLAP_SOCK_IS_READ(s); + Debug( LDAP_DEBUG_CONNS, "daemon: removing %ld%s%s\n", - (long) s, SLAP_SOCK_IS_READ(s) ? "r" : "", + (long) s, + wasreader ? "r" : "", waswriter ? "w" : "" ); - if ( waswriter ) slap_daemon.sd_nwriters--; -#ifdef SLAP_LIGHTWEIGHT_LISTENER - SLAP_SOCK_CLR_SUSPEND(s); -#endif + if ( waswriter ) slap_daemon.sd_nwriters--; SLAP_DEL_SOCK(s); + /* If we ran out of file descriptors, we dropped a listener from * the select() loop. Now that we're removing a session from our * control, we can try to resume a dropped listener to use. @@ -541,14 +502,14 @@ void slapd_remove( if ( emfile ) { int i; for ( i = 0; slap_listeners[i] != NULL; i++ ) { - if ( slap_listeners[i]->sl_sd != AC_SOCKET_INVALID ) { - if ( slap_listeners[i]->sl_sd == s ) continue; + Listener *lr = slap_listeners[i]; - if ( slap_listeners[i]->sl_is_mute ) { - slap_listeners[i]->sl_is_mute = 0; - emfile--; - break; - } + if ( lr->sl_sd == AC_SOCKET_INVALID ) continue; + if ( lr->sl_sd == s ) continue; + if ( lr->sl_mute ) { + lr->sl_mute = 0; + emfile--; + break; } } /* Walked the entire list without enabling anything; emfile @@ -560,45 +521,6 @@ void slapd_remove( WAKE_LISTENER(wake || slapd_gentle_shutdown == 2); } -#ifdef SLAP_LIGHTWEIGHT_LISTENER -/* - * Temporarily suspend submitting events on the descriptor to the pool. - * Reading on the descriptor will be resumed by a connection procseeing thread - * when data (LDAP requests) on it are read. - * slapd_suspend() returns 1 when it is suspended otherwise returns 0 - */ -int slapd_suspend(ber_socket_t s) { - int rc = 0; - - ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex ); - - if ( !SLAP_SOCK_IS_SUSPEND( s ) && SLAP_SOCK_IS_ACTIVE( s ) && - SLAP_SOCK_IS_READ( s ) ) - { - SLAP_SOCK_SET_SUSPEND( s ); - SLAP_SOCK_CLR_READ( s ); - rc = 1; - } - - ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex ); - return rc; -} - -void slapd_resume ( ber_socket_t s ) { - ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex ); - - SLAP_SOCK_SET_READ( s ); - - assert( SLAP_SOCK_IS_SUSPEND( s ) ); - - SLAP_SOCK_CLR_SUSPEND ( s ); - - ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex ); - - WAKE_LISTENER(1); -} -#endif - void slapd_clr_write(ber_socket_t s, int wake) { ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex ); @@ -627,14 +549,18 @@ void slapd_set_write(ber_socket_t s, int wake) { WAKE_LISTENER(wake); } -void slapd_clr_read(ber_socket_t s, int wake) { +int slapd_clr_read(ber_socket_t s, int wake) { + int rc = 1; ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex ); - assert( SLAP_SOCK_IS_ACTIVE( s )); - SLAP_SOCK_CLR_READ( s ); - + if ( SLAP_SOCK_IS_ACTIVE( s )) { + SLAP_SOCK_CLR_READ( s ); + rc = 0; + } ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex ); - WAKE_LISTENER(wake); + if ( !rc ) + WAKE_LISTENER(wake); + return rc; } void slapd_set_read(ber_socket_t s, int wake) { @@ -653,8 +579,7 @@ static void slapd_close(ber_socket_t s) { tcp_close(s); } -static void slap_free_listener_addresses(struct sockaddr **sal) -{ +static void slap_free_listener_addresses(struct sockaddr **sal) { struct sockaddr **sap; if (sal == NULL) return; for (sap = sal; *sap != NULL; sap++) ch_free(*sap); @@ -786,7 +711,7 @@ static int slap_get_listener_addresses( snprintf(serv, sizeof serv, "%d", port); if ( (err = getaddrinfo(host, serv, &hints, &res)) ) { - Debug( LDAP_DEBUG_ANY, "daemon: getaddrinfo failed: %s\n", + Debug( LDAP_DEBUG_ANY, "daemon: getaddrinfo() failed: %s\n", AC_GAI_STRERROR(err), 0, 0); return -1; } @@ -919,7 +844,10 @@ static int slap_open_listener( } l.sl_url.bv_val = NULL; - l.sl_is_mute = 0; + l.sl_mute = 0; +#ifdef SLAP_LIGHTWEIGHT_DISPATCHER + l.sl_busy = 0; +#endif #ifndef HAVE_TLS if( ldap_pvt_url_scheme2tls( lud->lud_scheme ) ) { @@ -1170,7 +1098,7 @@ static int slap_open_listener( return -1; } - Debug( LDAP_DEBUG_TRACE, "daemon: initialized %s\n", + Debug( LDAP_DEBUG_TRACE, "daemon: listener initialized %s\n", l.sl_url.bv_val, 0, 0 ); return 0; } @@ -1245,6 +1173,7 @@ int slapd_daemon_init( const char *urls ) Debug( LDAP_DEBUG_TRACE, "daemon_init: %d listeners opened\n", i, 0, 0 ); + #ifdef HAVE_SLP if( slapd_register_slp ) { slapd_slp_init( urls ); @@ -1255,6 +1184,10 @@ int slapd_daemon_init( const char *urls ) ldap_charray_free( u ); ldap_pvt_thread_mutex_init( &slap_daemon.sd_mutex ); +#ifdef HAVE_TCPD + ldap_pvt_thread_mutex_init( &slap_daemon.tcpd_mutex ); +#endif + return !i; } @@ -1274,6 +1207,11 @@ slapd_daemon_destroy(void) } #endif +#ifdef HAVE_TCPD + ldap_pvt_thread_mutex_destroy( &slap_daemon.tcpd_mutex ); +#endif + + ldap_pvt_thread_mutex_destroy( &slap_daemon.sd_mutex ); return 0; } @@ -1285,33 +1223,35 @@ close_listeners( int l; for ( l = 0; slap_listeners[l] != NULL; l++ ) { - if ( slap_listeners[l]->sl_sd != AC_SOCKET_INVALID ) { - if ( remove ) slapd_remove( slap_listeners[l]->sl_sd, 0, 0 ); + Listener *lr = slap_listeners[l]; + + if ( lr->sl_sd != AC_SOCKET_INVALID ) { + if ( remove ) slapd_remove( lr->sl_sd, 0, 0, 0 ); #ifdef LDAP_PF_LOCAL - if ( slap_listeners[l]->sl_sa.sa_addr.sa_family == AF_LOCAL ) { - unlink( slap_listeners[l]->sl_sa.sa_un_addr.sun_path ); + if ( lr->sl_sa.sa_addr.sa_family == AF_LOCAL ) { + unlink( lr->sl_sa.sa_un_addr.sun_path ); } #endif /* LDAP_PF_LOCAL */ - slapd_close( slap_listeners[l]->sl_sd ); + slapd_close( lr->sl_sd ); } - if ( slap_listeners[l]->sl_url.bv_val ) { - ber_memfree( slap_listeners[l]->sl_url.bv_val ); + if ( lr->sl_url.bv_val ) { + ber_memfree( lr->sl_url.bv_val ); } - if ( slap_listeners[l]->sl_name.bv_val ) { - ber_memfree( slap_listeners[l]->sl_name.bv_val ); + if ( lr->sl_name.bv_val ) { + ber_memfree( lr->sl_name.bv_val ); } - free ( slap_listeners[l] ); + free( lr ); slap_listeners[l] = NULL; } } static int -slapd_handle_listener( +slap_listener( Listener *sl ) { Sockaddr from; @@ -1338,18 +1278,7 @@ slapd_handle_listener( peername[0] = '\0'; #ifdef LDAP_CONNECTIONLESS - if ( sl->sl_is_udp ) { - /* The first time we receive a query, we set this - * up as a "connection". It remains open for the life - * of the slapd. - */ - if ( sl->sl_is_udp < 2 ) { - id = connection_init( sl->sl_sd, sl, "", "", - CONN_IS_UDP, ssf, NULL ); - sl->sl_is_udp++; - } - return 1; - } + if ( sl->sl_is_udp ) return 1; #endif # ifdef LDAP_PF_LOCAL @@ -1359,13 +1288,15 @@ slapd_handle_listener( # endif /* LDAP_PF_LOCAL */ s = accept( sl->sl_sd, (struct sockaddr *) &from, &len ); -#ifdef SLAP_LIGHTWEIGHT_LISTENER - /* - * As soon as a TCP connection is accepted, the listener FD is resumed - * for concurrent-processing of incoming TCP connections. + +#ifdef SLAP_LIGHTWEIGHT_DISPATCHER + /* Resume the listener FD to allow concurrent-processing of + * additional incoming connections. */ - slapd_resume( sl->sl_sd ); + sl->sl_busy = 0; + WAKE_LISTENER(1); #endif + if ( s == AC_SOCKET_INVALID ) { int err = sock_errno(); @@ -1381,14 +1312,13 @@ slapd_handle_listener( ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex ); emfile++; /* Stop listening until an existing session closes */ - sl->sl_is_mute = 1; + sl->sl_mute = 1; ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex ); } Debug( LDAP_DEBUG_ANY, "daemon: accept(%ld) failed errno=%d (%s)\n", - (long) sl->sl_sd, err, - sock_errstr(err) ); + (long) sl->sl_sd, err, sock_errstr(err) ); ldap_pvt_thread_yield(); return 0; } @@ -1408,10 +1338,8 @@ slapd_handle_listener( #ifdef LDAP_DEBUG ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex ); - /* newly accepted stream should not be in any of the FD SETS */ assert( SLAP_SOCK_NOT_ACTIVE( s )); - ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex ); #endif @@ -1450,8 +1378,10 @@ slapd_handle_listener( } #endif - Debug( LDAP_DEBUG_CONNS, "daemon: new connection on %ld\n", - (long) s, 0, 0 ); + Debug( LDAP_DEBUG_CONNS, + "daemon: listen=%ld, new connection on %ld\n", + (long) sl->sl_sd, (long) s, 0 ); + switch ( from.sa_addr.sa_family ) { # ifdef LDAP_PF_LOCAL case AF_LOCAL: @@ -1538,20 +1468,25 @@ slapd_handle_listener( #endif /* SLAPD_RLOOKUPS */ #ifdef HAVE_TCPD - if ( !hosts_ctl("slapd", - dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN, - peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN, - SLAP_STRING_UNKNOWN )) { - /* DENY ACCESS */ - Statslog( LDAP_DEBUG_STATS, - "fd=%ld DENIED from %s (%s)\n", - (long) s, + int rc; + ldap_pvt_thread_mutex_lock( &slap_daemon.tcpd_mutex ); + rc = hosts_ctl("slapd", dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN, peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN, - 0, 0 ); - slapd_close(s); - return 0; + SLAP_STRING_UNKNOWN ); + ldap_pvt_thread_mutex_unlock( &slap_daemon.tcpd_mutex ); + if ( !rc ) { + /* DENY ACCESS */ + Statslog( LDAP_DEBUG_STATS, + "fd=%ld DENIED from %s (%s)\n", + (long) s, + dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN, + peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN, + 0, 0 ); + slapd_close(s); + return 0; + } } #endif /* HAVE_TCPD */ } @@ -1582,47 +1517,47 @@ slapd_handle_listener( id, (long) s, peername, sl->sl_name.bv_val, 0 ); - slapd_add( s, 1, NULL ); return 0; } -#ifdef SLAP_LIGHTWEIGHT_LISTENER -void* -slapd_handle_listener_thread( +#ifdef SLAP_LIGHTWEIGHT_DISPATCHER +static void* +slap_listener_thread( void* ctx, void* ptr ) { int rc; - rc = slapd_handle_listener( (Listener*)ptr ); + rc = slap_listener( (Listener*)ptr ); if( rc != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_ANY, - "slapd_handle_listener_thread: failed", 0, 0, 0 ); + "listener_thread: failed %d", rc, 0, 0 ); } return (void*)NULL; } static int -new_connection_activate( +slap_listener_activate( Listener* sl ) { - int status; + int rc; + + Debug( LDAP_DEBUG_TRACE, "slap_listener_activate(%d): %s\n", + sl->sl_sd, sl->sl_busy ? "busy" : "", 0 ); - if( !slapd_suspend( sl->sl_sd ) ) return (0); + sl->sl_busy++; - status = ldap_pvt_thread_pool_submit( &connection_pool, - slapd_handle_listener_thread, (void *) sl ); + rc = ldap_pvt_thread_pool_submit( &connection_pool, + slap_listener_thread, (void *) sl ); - if( status != 0 ) { + if( rc != 0 ) { Debug( LDAP_DEBUG_ANY, - "new_connection_activate: ldap_pvt_thread_pool_submit failed\n", - 0, 0, 0 ); - return (-1); + "listener_activate(%d): submit failed (%d)\n", + sl->sl_sd, rc, 0 ); } - - return (0); + return rc; } #endif @@ -1662,10 +1597,8 @@ slapd_daemon_task( * listening port. The listen() and accept() calls * are unnecessary. */ - if ( slap_listeners[l]->sl_is_udp ) { - slapd_add( slap_listeners[l]->sl_sd, 1, slap_listeners[l] ); + if ( slap_listeners[l]->sl_is_udp ) continue; - } #endif if ( listen( slap_listeners[l]->sl_sd, SLAPD_LISTEN_BACKLOG ) == -1 ) { @@ -1713,7 +1646,7 @@ slapd_daemon_task( return (void*)-1; } -#ifdef SLAP_LIGHTWEIGHT_LISTENER +#ifdef SLAP_LIGHTWEIGHT_DISPATCHER /* make the listening socket non-blocking */ if ( ber_pvt_socket_set_nonblock( slap_listeners[l]->sl_sd, 1 ) < 0 ) { Debug( LDAP_DEBUG_ANY, "slapd_daemon_task: " @@ -1728,7 +1661,7 @@ slapd_daemon_task( } #ifdef HAVE_NT_SERVICE_MANAGER - if ( started_event != NULL ) } + if ( started_event != NULL ) { ldap_pvt_thread_cond_signal( &started_event ); } #endif @@ -1779,9 +1712,13 @@ slapd_daemon_task( ber_socket_t active; if( slapd_gentle_shutdown == 1 ) { + BackendDB *be; Debug( LDAP_DEBUG_ANY, "slapd gentle shutdown\n", 0, 0, 0 ); close_listeners( 1 ); frontendDB->be_restrictops |= SLAP_RESTRICT_OP_WRITES; + LDAP_STAILQ_FOREACH(be, &backendDB, be_next) { + be->be_restrictops |= SLAP_RESTRICT_OP_WRITES; + } slapd_gentle_shutdown = 2; } @@ -1789,29 +1726,36 @@ slapd_daemon_task( active = slap_daemon.sd_nactives; ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex ); if( active == 0 ) { - slapd_shutdown = 2; + slapd_shutdown = 1; break; } } #endif - at = 0; ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex ); nwriters = slap_daemon.sd_nwriters; - SLAP_EVENT_INIT; for ( l = 0; slap_listeners[l] != NULL; l++ ) { - if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID ) continue; + Listener *lr = slap_listeners[l]; + + if ( lr->sl_sd == AC_SOCKET_INVALID ) continue; - if ( slap_listeners[l]->sl_is_mute ) { - SLAP_SOCK_SET_MUTE( slap_listeners[l]->sl_sd ); - } else if ( SLAP_SOCK_IS_MUTE( slap_listeners[l]->sl_sd )) { - SLAP_SOCK_CLR_MUTE( slap_listeners[l]->sl_sd ); +#ifdef SLAP_LIGHTWEIGHT_DISPATCHER + if ( lr->sl_mute || lr->sl_busy ) +#else + if ( lr->sl_mute ) +#endif + { + SLAP_SOCK_CLR_READ( lr->sl_sd ); + } else { + SLAP_SOCK_SET_READ( lr->sl_sd ); } } + SLAP_EVENT_INIT; + nfds = SLAP_EVENT_MAX; if ( global_idletimeout && slap_daemon.sd_nactives ) at = 1; @@ -1857,16 +1801,31 @@ slapd_daemon_task( } for ( l = 0; slap_listeners[l] != NULL; l++ ) { - if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID || - slap_listeners[l]->sl_is_mute ) - { + Listener *lr = slap_listeners[l]; + + if ( lr->sl_sd == AC_SOCKET_INVALID ) { + continue; + } + + if ( lr->sl_mute ) { + Debug( LDAP_DEBUG_CONNS, + "daemon: select: listen=%d muted\n", + lr->sl_sd, 0, 0 ); continue; } +#ifdef SLAP_LIGHTWEIGHT_DISPATCHER + if ( lr->sl_busy ) { + Debug( LDAP_DEBUG_CONNS, + "daemon: select: listen=%d busy\n", + lr->sl_sd, 0, 0 ); + continue; + } +#endif + Debug( LDAP_DEBUG_CONNS, "daemon: select: listen=%d active_threads=%d tvp=%s\n", - slap_listeners[l]->sl_sd, at, - tvp == NULL ? "NULL" : "zero" ); + lr->sl_sd, at, tvp == NULL ? "NULL" : "zero" ); } switch(ns = SLAP_EVENT_WAIT(tvp)) { @@ -1906,18 +1865,19 @@ slapd_daemon_task( if( slapd_shutdown ) continue; ebadf = 0; - Debug( LDAP_DEBUG_CONNS, "daemon: activity on %d descriptors\n", - ns, 0, 0 ); + Debug( LDAP_DEBUG_CONNS, + "daemon: activity on %d descriptor%s\n", + ns, ns != 1 ? "s" : "", 0 ); /* FALL THRU */ } #if SLAP_EVENTS_ARE_INDEXED if ( SLAP_EVENT_IS_READ( wake_sds[0] )) { char c[BUFSIZ]; - tcp_read( wake_sds[0], c, sizeof(c) ); - waking = 0; - ns--; SLAP_EVENT_CLR_READ( wake_sds[0] ); + waking = 0; + tcp_read( wake_sds[0], c, sizeof(c) ); + Debug( LDAP_DEBUG_CONNS, "daemon: waked\n", 0, 0, 0 ); continue; } @@ -1930,25 +1890,21 @@ slapd_daemon_task( if ( ns <= 0 ) break; if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID ) continue; +#ifdef LDAP_CONNECTIONLESS + if ( slap_listeners[l]->sl_is_udp ) continue; +#endif if ( !SLAP_EVENT_IS_READ( slap_listeners[l]->sl_sd )) continue; + /* clear events */ + SLAP_EVENT_CLR_READ( slap_listeners[l]->sl_sd ); + SLAP_EVENT_CLR_WRITE( slap_listeners[l]->sl_sd ); + ns--; -#ifdef SLAP_LIGHTWEIGHT_LISTENER - rc = new_connection_activate(slap_listeners[l]); +#ifdef SLAP_LIGHTWEIGHT_DISPATCHER + rc = slap_listener_activate(slap_listeners[l]); #else - rc = slapd_handle_listener(slap_listeners[l]); -#endif - -#ifdef LDAP_CONNECTIONLESS - /* This is a UDP session, let the data loop process it */ - if ( rc ) continue; + rc = slap_listener(slap_listeners[l]); #endif - - ns--; - - /* Don't need to look at this in the data loops */ - SLAP_EVENT_CLR_READ( slap_listeners[l]->sl_sd ); - SLAP_EVENT_CLR_WRITE( slap_listeners[l]->sl_sd ); } /* bypass the following tests if no descriptors left */ @@ -2005,23 +1961,26 @@ slapd_daemon_task( #ifdef HAVE_WINSOCK wd = writefds.fd_array[i]; #else - if( ! SLAP_EVENT_IS_WRITE( i ) ) { - continue; - } + if( ! SLAP_EVENT_IS_WRITE( i ) ) continue; wd = i; #endif + + SLAP_EVENT_CLR_WRITE( wd ); nwfds--; Debug( LDAP_DEBUG_CONNS, "daemon: write active on %d\n", wd, 0, 0 ); + +#ifdef SLAP_LIGHTWEIGHT_DISPATCHER + connection_write_activate( wd ); +#else /* * NOTE: it is possible that the connection was closed * and that the stream is now inactive. - * connection_write() must validitate the stream is still + * connection_write() must validate the stream is still * active. */ - if ( connection_write( wd ) < 0 ) { if ( SLAP_EVENT_IS_READ( wd )) { SLAP_EVENT_CLR_READ( (unsigned) wd ); @@ -2029,7 +1988,7 @@ slapd_daemon_task( } slapd_close( wd ); } - SLAP_EVENT_CLR_WRITE( wd ); +#endif } for ( i = 0; nrfds > 0; i++ ) { @@ -2037,11 +1996,10 @@ slapd_daemon_task( #ifdef HAVE_WINSOCK rd = readfds.fd_array[i]; #else - if( ! SLAP_EVENT_IS_READ( i ) ) { - continue; - } + if( ! SLAP_EVENT_IS_READ( i ) ) continue; rd = i; #endif + SLAP_EVENT_CLR_READ( rd ); nrfds--; Debug ( LDAP_DEBUG_CONNS, @@ -2053,8 +2011,8 @@ slapd_daemon_task( * active. */ -#ifdef SLAP_LIGHTWEIGHT_LISTENER - connection_processing_activate( rd ); +#ifdef SLAP_LIGHTWEIGHT_DISPATCHER + connection_read_activate( rd ); #else if ( connection_read( rd ) < 0 ) { slapd_close( rd ); @@ -2074,24 +2032,17 @@ slapd_daemon_task( * an event, so we could use pointers to the listener structure * instead of just the file descriptor. For /dev/poll we have to * search the listeners array for a matching descriptor. + * + * We now handle wake events when we see them; they are not given + * higher priority. */ - /* if waking is set and we woke up, we'll read whatever - * we can. - */ - if ( waking ) { - char c[BUFSIZ]; - tcp_read( wake_sds[0], c, sizeof(c) ); - waking = 0; - ns--; - continue; - } - #ifdef LDAP_DEBUG Debug( LDAP_DEBUG_CONNS, "daemon: activity on:", 0, 0, 0 ); for (i=0; isl_is_udp) @@ -2111,18 +2062,20 @@ slapd_daemon_task( r ? "r" : "", w ? "w" : "" ); } } + Debug( LDAP_DEBUG_CONNS, "\n", 0, 0, 0 ); #endif for (i=0; isl_is_udp ) { + continue; + } + + id = connection_init( lr->sl_sd, lr, "", "", CONN_IS_UDP, (slap_ssf_t) 0, NULL ); + + if( id < 0 ) { + Debug( LDAP_DEBUG_TRACE, + "connectionless_init: failed on %s (%d)\n", lr->sl_url, lr->sl_sd, 0 ); + return -1; + } + lr->sl_is_udp++; + } + + return 0; +} +#endif /* LDAP_CONNECTIONLESS */ + int slapd_daemon( void ) { int rc; connections_init(); +#ifdef LDAP_CONNECTIONLESS + connectionless_init(); +#endif #define SLAPD_LISTENER_THREAD 1 #if defined( SLAPD_LISTENER_THREAD )