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 )