X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fdaemon.c;h=fc204710a922ace44cf854e8f06423a42be513f2;hb=4f05d992f2146921dbc13d3477de9918f20172b9;hp=2a75f91753ac3fc152e2b735a0935ba63cb0e8ce;hpb=cfa8dd6884f7d45154fb92651fd6e04aeb93dd0b;p=openldap diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c index 2a75f91753..fc204710a9 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-2012 The OpenLDAP Foundation. + * Copyright 1998-2014 The OpenLDAP Foundation. * Portions Copyright 2007 by Howard Chu, Symas Corporation. * All rights reserved. * @@ -41,6 +41,10 @@ #include "ldap_rq.h" +#ifdef HAVE_POLL +#include +#endif + #if defined(HAVE_SYS_EPOLL_H) && defined(HAVE_EPOLL) # include #elif defined(SLAP_X_DEVPOLL) && defined(HAVE_SYS_DEVPOLL_H) && defined(HAVE_DEVPOLL) @@ -73,7 +77,9 @@ ber_socket_t dtblsize; slap_ssf_t local_ssf = LDAP_PVT_SASL_LOCAL_SSF; struct runqueue_s slapd_rq; -#define MAX_DAEMON_THREADS 16 +#ifndef SLAPD_MAX_DAEMON_THREADS +#define SLAPD_MAX_DAEMON_THREADS 16 +#endif int slapd_daemon_threads = 1; int slapd_daemon_mask; @@ -84,6 +90,7 @@ int slapd_tcp_wmem; Listener **slap_listeners = NULL; static volatile sig_atomic_t listening = 1; /* 0 when slap_listeners closed */ +static ldap_pvt_thread_t *listener_tid; #ifndef SLAPD_LISTEN_BACKLOG #define SLAPD_LISTEN_BACKLOG 1024 @@ -91,11 +98,9 @@ static volatile sig_atomic_t listening = 1; /* 0 when slap_listeners closed */ #define DAEMON_ID(fd) (fd & slapd_daemon_mask) -static ber_socket_t wake_sds[MAX_DAEMON_THREADS][2]; +static ber_socket_t wake_sds[SLAPD_MAX_DAEMON_THREADS][2]; static int emfile; -static time_t chk_writetime; - static volatile int waking; #ifdef NO_THREADS #define WAKE_LISTENER(l,w) do { \ @@ -157,7 +162,7 @@ typedef struct slap_daemon_st { #endif /* ! epoll && ! /dev/poll */ } slap_daemon_st; -static slap_daemon_st slap_daemon[MAX_DAEMON_THREADS]; +static slap_daemon_st slap_daemon[SLAPD_MAX_DAEMON_THREADS]; /* * NOTE: naming convention for macros: @@ -961,14 +966,6 @@ slapd_set_write( ber_socket_t s, int wake ) SLAP_SOCK_SET_WRITE( id, s ); slap_daemon[id].sd_nwriters++; } - if (( wake & 2 ) && global_writetimeout && !chk_writetime ) { - if (id) - ldap_pvt_thread_mutex_lock( &slap_daemon[0].sd_mutex ); - if (!chk_writetime) - chk_writetime = slap_get_time(); - if (id) - ldap_pvt_thread_mutex_unlock( &slap_daemon[0].sd_mutex ); - } ldap_pvt_thread_mutex_unlock( &slap_daemon[id].sd_mutex ); WAKE_LISTENER(id,wake); @@ -1008,25 +1005,6 @@ slapd_set_read( ber_socket_t s, int wake ) WAKE_LISTENER(id,wake); } -time_t -slapd_get_writetime() -{ - time_t cur; - ldap_pvt_thread_mutex_lock( &slap_daemon[0].sd_mutex ); - cur = chk_writetime; - ldap_pvt_thread_mutex_unlock( &slap_daemon[0].sd_mutex ); - return cur; -} - -void -slapd_clr_writetime( time_t old ) -{ - ldap_pvt_thread_mutex_lock( &slap_daemon[0].sd_mutex ); - if ( chk_writetime == old ) - chk_writetime = 0; - ldap_pvt_thread_mutex_unlock( &slap_daemon[0].sd_mutex ); -} - static void slapd_close( ber_socket_t s ) { @@ -1038,6 +1016,14 @@ slapd_close( ber_socket_t s ) #endif } +void +slapd_shutsock( ber_socket_t s ) +{ + Debug( LDAP_DEBUG_CONNS, "daemon: shutdown socket %ld\n", + (long) s, 0, 0 ); + shutdown( SLAP_FD2SOCK(s), 2 ); +} + static void slap_free_listener_addresses( struct sockaddr **sal ) { @@ -1608,7 +1594,7 @@ slapd_daemon_init( const char *urls ) Debug( LDAP_DEBUG_ARGS, "daemon_init: %s\n", urls ? urls : "", 0, 0 ); - for ( i=0; isl_name.bv_val ); slapd_close(sfd); - return 0; } - Statslog( LDAP_DEBUG_STATS, - "conn=%ld fd=%ld ACCEPT from %s (%s)\n", - c->c_connid, (long) sfd, peername, sl->sl_name.bv_val, - 0 ); - return 0; } @@ -2129,7 +2109,7 @@ slapd_daemon_task( int l; time_t last_idle_check = 0; int ebadf = 0; - int tid = *(int *)ptr; + int tid = (ldap_pvt_thread_t *) ptr - listener_tid; #define SLAPD_IDLE_CHECK_LIMIT 4 @@ -2368,18 +2348,13 @@ loop: now = slap_get_time(); - if ( !tid && ( global_idletimeout > 0 || chk_writetime )) { + if ( !tid && ( global_idletimeout > 0 )) { 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 = 0; - 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 ); @@ -2456,7 +2431,7 @@ loop: nfds = SLAP_EVENT_MAX(tid); - if (( chk_writetime || global_idletimeout ) && slap_daemon[tid].sd_nactives ) at = 1; + if (( global_idletimeout ) && slap_daemon[tid].sd_nactives ) at = 1; ldap_pvt_thread_mutex_unlock( &slap_daemon[tid].sd_mutex ); @@ -2889,12 +2864,14 @@ int slapd_daemon( void ) { int i, rc; - ldap_pvt_thread_t *listener_tid; #ifdef LDAP_CONNECTIONLESS connectionless_init(); #endif /* LDAP_CONNECTIONLESS */ + if ( slapd_daemon_threads > SLAPD_MAX_DAEMON_THREADS ) + slapd_daemon_threads = SLAPD_MAX_DAEMON_THREADS; + listener_tid = ch_malloc(slapd_daemon_threads * sizeof(ldap_pvt_thread_t)); /* daemon_init only inits element 0 */ @@ -2916,7 +2893,7 @@ slapd_daemon( void ) { /* listener as a separate THREAD */ rc = ldap_pvt_thread_create( &listener_tid[i], - 0, slapd_daemon_task, (void *)&i ); + 0, slapd_daemon_task, &listener_tid[i] ); if ( rc != 0 ) { Debug( LDAP_DEBUG_ANY, @@ -2931,6 +2908,7 @@ slapd_daemon( void ) destroy_listeners(); ch_free( listener_tid ); + listener_tid = NULL; return 0; } @@ -3083,3 +3061,34 @@ slap_wake_listener() { WAKE_LISTENER(0,1); } + +/* return 0 on timeout, 1 on writer ready + * -1 on general error + */ +int +slapd_wait_writer( ber_socket_t sd ) +{ +#ifdef HAVE_WINSOCK + fd_set writefds; + struct timeval tv, *tvp; + + FD_ZERO( &writefds ); + FD_SET( slapd_ws_sockets[sd], &writefds ); + if ( global_writetimeout ) { + tv.tv_sec = global_writetimeout; + tv.tv_usec = 0; + tvp = &tv; + } else { + tvp = NULL; + } + return select( 0, NULL, &writefds, NULL, tvp ); +#else + struct pollfd fds; + int timeout = global_writetimeout ? global_writetimeout * 1000 : -1; + + fds.fd = sd; + fds.events = POLLOUT; + + return poll( &fds, 1, timeout ); +#endif +}