X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fdaemon.c;h=2893a905f90c1f05de7eb85f2332dd0cd2605439;hb=ac3ad635ef0883d96b5424f96b2c43e13b0ad659;hp=737177413a76ecbc416a541f4d5c29695a9b7f8f;hpb=b4e10e194d9cc7d9f70f8dac48f94c2c1c0166f2;p=openldap
diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c
index 737177413a..2893a905f9 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-2004 The OpenLDAP Foundation.
+ * Copyright 1998-2005 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -40,9 +40,9 @@
#include "ldap_rq.h"
-#define HAVE_EPOLL 1
+#undef HAVE_EPOLL
-#ifdef HAVE_EPOLL
+#if defined(HAVE_SYS_EPOLL_H) && defined(HAVE_EPOLL)
#include
#endif
@@ -72,6 +72,7 @@ int slap_inet4or6 = AF_INET;
time_t starttime;
ber_socket_t dtblsize;
slap_ssf_t local_ssf = LDAP_PVT_SASL_LOCAL_SSF;
+struct runqueue_s slapd_rq;
Listener **slap_listeners = NULL;
@@ -82,7 +83,7 @@ static int emfile;
static int waking;
#define WAKE_LISTENER(w) \
-do { if (w && waking < 5) { tcp_write( wake_sds[1], "0", 1 ); waking++;} } while(0)
+do { if (w && waking < 5) { waking++; tcp_write( wake_sds[1], "0", 1 ); } } while(0)
volatile sig_atomic_t slapd_shutdown = 0, slapd_gentle_shutdown = 0;
volatile sig_atomic_t slapd_abrupt_shutdown = 0;
@@ -117,30 +118,29 @@ static struct slap_daemon {
#define SLAP_EVENTS_ARE_INDEXED 0
#define SLAP_SOCK_IX(s) (slap_daemon.sd_index[s])
#define SLAP_SOCK_EP(s) (slap_daemon.sd_epolls[SLAP_SOCK_IX(s)])
-#define SLAP_SOCK_FD(s) (SLAP_SOCK_EP(s).data.fd)
#define SLAP_SOCK_EV(s) (SLAP_SOCK_EP(s).events)
-#define SLAP_SOCK_IS_ACTIVE(s) (SLAP_SOCK_IX(s) != -1 && SLAP_SOCK_FD(s) == s)
+#define SLAP_SOCK_IS_ACTIVE(s) (SLAP_SOCK_IX(s) != -1)
#define SLAP_SOCK_NOT_ACTIVE(s) (SLAP_SOCK_IX(s) == -1)
#define SLAP_SOCK_IS_SET(s, mode) (SLAP_SOCK_EV(s) & mode)
#define SLAP_SOCK_IS_READ(s) SLAP_SOCK_IS_SET(s, EPOLLIN)
#define SLAP_SOCK_IS_WRITE(s) SLAP_SOCK_IS_SET(s, EPOLLOUT)
-#define SLAP_SET_SOCK(s, events) do { \
- if ((SLAP_SOCK_EV(s) & events) != events) { \
- SLAP_SOCK_EV(s) |= events; \
+#define SLAP_SET_SOCK(s, mode) do { \
+ if ((SLAP_SOCK_EV(s) & mode) != mode) { \
+ SLAP_SOCK_EV(s) |= mode; \
epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_MOD, s, \
&SLAP_SOCK_EP(s)); \
} \
} while(0)
-#define SLAP_CLR_SOCK(s, events) do { \
- if ((SLAP_SOCK_EV(s) & events)) { \
- SLAP_SOCK_EV(s) &= ~events; \
+#define SLAP_CLR_SOCK(s, mode) do { \
+ if ((SLAP_SOCK_EV(s) & mode)) { \
+ SLAP_SOCK_EV(s) &= ~mode; \
epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_MOD, s, \
&SLAP_SOCK_EP(s)); \
} \
-} while(0) \
+} while(0)
#define SLAP_SOCK_SET_READ(s) SLAP_SET_SOCK(s, EPOLLIN)
#define SLAP_SOCK_SET_WRITE(s) SLAP_SET_SOCK(s, EPOLLOUT)
@@ -148,40 +148,59 @@ static struct slap_daemon {
#define SLAP_SOCK_CLR_READ(s) SLAP_CLR_SOCK(s, EPOLLIN)
#define SLAP_SOCK_CLR_WRITE(s) SLAP_CLR_SOCK(s, EPOLLOUT)
-#define SLAP_CLR_EVENT(i, events) (revents[i].events &= ~events)
-
-#define SLAP_EVENT_CLR_READ(i) SLAP_CLR_EVENT(i, EPOLLIN)
-#define SLAP_EVENT_CLR_WRITE(i) SLAP_CLR_EVENT(i, EPOLLOUT)
-
-#define SLAP_CHK_EVENT(i, events) (revents[i].events & events)
-
-#define SLAP_EVENT_IS_READ(i) SLAP_CHK_EVENT(i, EPOLLIN)
-#define SLAP_EVENT_IS_WRITE(i) SLAP_CHK_EVENT(i, EPOLLOUT)
+#define SLAP_CLR_EVENT(i, mode) (revents[i].events &= ~mode)
-#define SLAP_EVENT_FD(i) (revents[i].data.fd)
#define SLAP_EVENT_MAX slap_daemon.sd_nfds
-#define SLAP_ADD_SOCK(s) do { \
+/* If a Listener address is provided, store that as the epoll data.
+ * Otherwise, store the address of this socket's slot in the
+ * index array. If we can't do this add, the system is out of
+ * resources and we need to shutdown.
+ */
+#define SLAP_ADD_SOCK(s, l) do { \
int rc; \
SLAP_SOCK_IX(s) = slap_daemon.sd_nfds; \
- SLAP_SOCK_FD(s) = s; \
+ SLAP_SOCK_EP(s).data.ptr = (l) ? (l) : (void *)(&SLAP_SOCK_IX(s)); \
SLAP_SOCK_EV(s) = EPOLLIN; \
rc = epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_ADD, s, \
&SLAP_SOCK_EP(s)); \
if ( rc == 0 ) slap_daemon.sd_nfds++; \
+ else { \
+ Debug( LDAP_DEBUG_ANY, "daemon: epoll_ctl ADD failed, errno %d, shutting down\n", \
+ errno, 0, 0 ); \
+ slapd_shutdown = 2; \
+ } \
} while(0)
+#define SLAP_EV_LISTENER(ptr) (((int *)(ptr) >= slap_daemon.sd_index && \
+ (int *)(ptr) <= (slap_daemon.sd_index+dtblsize)) ? 0 : 1)
+
+#define SLAP_EV_PTRFD(ptr) (SLAP_EV_LISTENER(ptr) ? \
+ ((Listener *)ptr)->sl_sd : (int *)(ptr) - slap_daemon.sd_index)
+
#define SLAP_DEL_SOCK(s) do { \
- int rc, index = SLAP_SOCK_IX(s); \
+ int fd, rc, 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]; \
- slap_daemon.sd_index[slap_daemon.sd_epolls[index].data.fd] = index; \
+ fd = SLAP_EV_PTRFD(slap_daemon.sd_epolls[index].data.ptr); \
+ slap_daemon.sd_index[fd] = index; \
slap_daemon.sd_index[s] = -1; \
slap_daemon.sd_nfds--; \
} while(0)
+#define SLAP_EVENT_CLR_READ(i) SLAP_CLR_EVENT(i, EPOLLIN)
+#define SLAP_EVENT_CLR_WRITE(i) SLAP_CLR_EVENT(i, EPOLLOUT)
+
+#define SLAP_CHK_EVENT(i, mode) (revents[i].events & mode)
+
+#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_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)
@@ -189,7 +208,9 @@ static struct slap_daemon {
#define SLAP_SOCK_SET_INIT \
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 )
+ slap_daemon.sd_epfd = epoll_create( dtblsize ); \
+ for (i=0; isl_name.bv_val,
0 );
- slapd_add( s, 1 );
+ slapd_add( s, 1, NULL );
return 0;
}
@@ -1461,6 +1489,7 @@ slapd_daemon_task(
int l;
time_t last_idle_check = 0;
struct timeval idle;
+ int ebadf = 0;
#define SLAPD_IDLE_CHECK_LIMIT 4
@@ -1478,7 +1507,7 @@ slapd_daemon_task(
idle.tv_usec = 0;
}
- slapd_add( wake_sds[0], 0 );
+ slapd_add( wake_sds[0], 0, NULL );
for ( l = 0; slap_listeners[l] != NULL; l++ ) {
if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID )
@@ -1489,7 +1518,7 @@ slapd_daemon_task(
* are unnecessary.
*/
if ( slap_listeners[l]->sl_is_udp ) {
- slapd_add( slap_listeners[l]->sl_sd, 1 );
+ slapd_add( slap_listeners[l]->sl_sd, 1, slap_listeners[l] );
continue;
}
#endif
@@ -1535,7 +1564,7 @@ slapd_daemon_task(
return( (void*)-1 );
}
- slapd_add( slap_listeners[l]->sl_sd, 0 );
+ slapd_add( slap_listeners[l]->sl_sd, 0, slap_listeners[l] );
}
#ifdef HAVE_NT_SERVICE_MANAGER
@@ -1551,7 +1580,6 @@ slapd_daemon_task(
int at;
ber_socket_t nfds, nrfds, nwfds;
#define SLAPD_EBADF_LIMIT 16
- int ebadf = 0;
time_t now;
@@ -1627,24 +1655,24 @@ slapd_daemon_task(
else
tvp = NULL;
- ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex );
- rtask = ldap_pvt_runqueue_next_sched( &syncrepl_rq, &cat );
+ ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
+ rtask = ldap_pvt_runqueue_next_sched( &slapd_rq, &cat );
while ( cat && cat->tv_sec && cat->tv_sec <= now ) {
- if ( ldap_pvt_runqueue_isrunning( &syncrepl_rq, rtask )) {
- ldap_pvt_runqueue_resched( &syncrepl_rq, rtask, 0 );
+ if ( ldap_pvt_runqueue_isrunning( &slapd_rq, rtask )) {
+ ldap_pvt_runqueue_resched( &slapd_rq, rtask, 0 );
} else {
- ldap_pvt_runqueue_runtask( &syncrepl_rq, rtask );
- ldap_pvt_runqueue_resched( &syncrepl_rq, rtask, 0 );
- ldap_pvt_thread_mutex_unlock( &syncrepl_rq.rq_mutex );
+ ldap_pvt_runqueue_runtask( &slapd_rq, rtask );
+ ldap_pvt_runqueue_resched( &slapd_rq, rtask, 0 );
+ ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
ldap_pvt_thread_pool_submit( &connection_pool,
rtask->routine, (void *) rtask );
- ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex );
+ ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
}
- rtask = ldap_pvt_runqueue_next_sched( &syncrepl_rq, &cat );
+ rtask = ldap_pvt_runqueue_next_sched( &slapd_rq, &cat );
}
- ldap_pvt_thread_mutex_unlock( &syncrepl_rq.rq_mutex );
+ ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
- if ( cat != NULL ) {
+ if ( cat && cat->tv_sec ) {
time_t diff = difftime( cat->tv_sec, now );
if ( diff == 0 )
diff = tdelta;
@@ -1692,10 +1720,12 @@ slapd_daemon_task(
case 0: /* timeout - let threads run */
ebadf = 0;
+#ifndef HAVE_YIELDING_SELECT
Debug( LDAP_DEBUG_CONNS, "daemon: select timeout - yielding\n",
0, 0, 0 );
ldap_pvt_thread_yield();
+#endif
continue;
default: /* something happened - deal with it */
@@ -1707,19 +1737,16 @@ slapd_daemon_task(
/* FALL THRU */
}
- /* We don't need to examine the event status for wake_sds;
- * if waking is set and we woke up, we'll read whatever
- * we can.
- */
- if ( waking ) {
+#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] );
continue;
}
-#if SLAP_EVENTS_ARE_INDEXED
/* The event slot equals the descriptor number - this is
* true for Unix select and poll. We treat Windows select
* like this too, even though it's a kludge.
@@ -1740,6 +1767,7 @@ slapd_daemon_task(
rc = slapd_handle_listener(slap_listeners[l]);
#ifdef LDAP_CONNECTIONLESS
+ /* This is a UDP session, let the data loop process it */
if ( rc ) continue;
#endif
@@ -1750,7 +1778,9 @@ slapd_daemon_task(
/* bypass the following tests if no descriptors left */
if ( ns <= 0 ) {
+#ifndef HAVE_YIELDING_SELECT
ldap_pvt_thread_yield();
+#endif
continue;
}
@@ -1824,6 +1854,7 @@ slapd_daemon_task(
}
slapd_close( wd );
}
+ SLAP_EVENT_CLR_WRITE( wd );
}
for ( i = 0; nrfds > 0; i++ )
@@ -1860,14 +1891,94 @@ slapd_daemon_task(
* all other connections last (as we do for select), we would need
* to use multiple event handles and cascade them.
*
- * That seems like a bit of hassle. So the wake_sds check has moved
- * above. For epoll and kqueue we can associate arbitrary data with
+ * That seems like a bit of hassle. So the wake_sds check has been
+ * skipped. For epoll and kqueue we can associate arbitrary data with
* 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.
*/
+ /* 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)
+#endif
+ ) continue;
+
+ r = SLAP_EVENT_IS_READ( i );
+ w = SLAP_EVENT_IS_WRITE( i );
+ if ( r || w ) {
+ Debug( LDAP_DEBUG_CONNS, " %d%s%s", SLAP_EVENT_FD(i),
+ r ? "r" : "", w ? "w" : "" );
+ }
+ }
#endif
+ for (i=0; i