From 05ec9552a745f8a7f784e4796e4d364eb31d9f4a Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Tue, 27 Jan 2009 08:00:50 +0000 Subject: [PATCH] Use epoll in edge-triggered mode --- servers/slapd/connection.c | 4 +-- servers/slapd/daemon.c | 52 +++++++++++++++++++++++++++++++++++--- servers/slapd/proto-slap.h | 2 ++ 3 files changed, 53 insertions(+), 5 deletions(-) diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c index 9e2130d6de..ae781817ab 100644 --- a/servers/slapd/connection.c +++ b/servers/slapd/connection.c @@ -1240,7 +1240,7 @@ int connection_read_activate( ber_socket_t s ) * thread reads data on it. Otherwise the listener thread will repeatedly * submit the same event on it to the pool. */ - rc = slapd_clr_read( s, 0 ); + rc = slapd_ack_read( s, 0 ); if ( rc ) return rc; @@ -1844,7 +1844,7 @@ int connection_write(ber_socket_t s) assert( connections != NULL ); - slapd_clr_write( s, 0 ); + slapd_ack_write( s, 0 ); c = connection_get( s ); if( c == NULL ) { diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c index 31720d2d78..fb01e403f3 100644 --- a/servers/slapd/daemon.c +++ b/servers/slapd/daemon.c @@ -161,6 +161,9 @@ 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)]) @@ -215,7 +218,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; \ + SLAP_EPOLL_SOCK_EV((s)) = EPOLLIN|EPOLLET; \ rc = epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_ADD, \ (s), &SLAP_EPOLL_SOCK_EP((s))); \ if ( rc == 0 ) { \ @@ -291,10 +294,12 @@ 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 /* @@ -470,6 +475,9 @@ 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 @@ -927,6 +935,24 @@ 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 ) { @@ -959,6 +985,26 @@ slapd_set_write( ber_socket_t s, int wake ) 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 ) { @@ -2513,7 +2559,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 ) ) { diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 5837bb50f2..3bfe126370 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -831,8 +831,10 @@ LDAP_SLAPD_F (void) slap_wake_listener LDAP_P((void)); LDAP_SLAPD_F (void) slapd_set_write LDAP_P((ber_socket_t s, int wake)); LDAP_SLAPD_F (void) slapd_clr_write LDAP_P((ber_socket_t s, int wake)); +LDAP_SLAPD_F (void) slapd_ack_write LDAP_P((ber_socket_t s, int wake)); LDAP_SLAPD_F (void) slapd_set_read LDAP_P((ber_socket_t s, int wake)); LDAP_SLAPD_F (int) slapd_clr_read LDAP_P((ber_socket_t s, int wake)); +LDAP_SLAPD_F (int) slapd_ack_read LDAP_P((ber_socket_t s, int wake)); LDAP_SLAPD_V (volatile sig_atomic_t) slapd_abrupt_shutdown; LDAP_SLAPD_V (volatile sig_atomic_t) slapd_shutdown; -- 2.39.5