&config_updateref, "( OLcfgDbAt:0.13 NAME 'olcUpdateRef' "
"EQUALITY caseIgnoreMatch "
"SUP labeledURI )", NULL, NULL },
+ { "writetimeout", "timeout", 2, 2, 0, ARG_INT,
+ &global_writetimeout, "( OLcfgGlAt:88 NAME 'olcWriteTimeout' "
+ "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
{ NULL, NULL, 0, 0, 0, ARG_IGNORED,
NULL, NULL, NULL, NULL }
};
"olcTLSCACertificatePath $ olcTLSCertificateFile $ "
"olcTLSCertificateKeyFile $ olcTLSCipherSuite $ olcTLSCRLCheck $ "
"olcTLSRandFile $ olcTLSVerifyClient $ olcTLSDHParamFile $ "
- "olcTLSCRLFile $ olcToolThreads $ "
+ "olcTLSCRLFile $ olcToolThreads $ olcWriteTimeout $ "
"olcObjectIdentifier $ olcAttributeTypes $ olcObjectClasses $ "
"olcDitContentRules $ olcLdapSyntaxes ) )", Cft_Global },
{ "( OLcfgGlOc:2 "
slap_mask_t global_disallows = 0;
int global_gentlehup = 0;
int global_idletimeout = 0;
+int global_writetimeout = 0;
char *global_host = NULL;
char *global_realm = NULL;
char *sasl_host = NULL;
*/
int connections_timeout_idle(time_t now)
{
- int i = 0;
+ int i = 0, writers = 0;
int connindex;
Connection* c;
+ time_t old;
+
+ old = slapd_get_writetime();
for( c = connection_first( &connindex );
c != NULL;
connection_closing( c, "idletimeout" );
connection_close( c );
i++;
+ continue;
+ }
+ if ( c->c_writewaiter ) {
+ writers = 1;
+ if( difftime( c->c_activitytime+global_writetimeout, now) < 0 ) {
+ /* close it */
+ connection_closing( c, "writetimeout" );
+ connection_close( c );
+ i++;
+ }
}
}
connection_done( c );
+ if ( !writers )
+ slapd_clr_writetime( old );
return i;
}
;
static int emfile;
+static time_t chk_writetime;
+
static volatile int waking;
#ifdef NO_THREADS
#define WAKE_LISTENER(w) do { \
SLAP_SOCK_SET_WRITE( s );
slap_daemon.sd_nwriters++;
}
+ if (( wake & 2 ) && global_writetimeout ) {
+ chk_writetime = slap_get_time();
+ }
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
WAKE_LISTENER(wake);
WAKE_LISTENER(wake);
}
+time_t
+slapd_get_writetime()
+{
+ time_t cur;
+ ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
+ cur = chk_writetime;
+ ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
+ return cur;
+}
+
+void
+slapd_clr_writetime( time_t old )
+{
+ ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
+ if ( chk_writetime == old )
+ chk_writetime = 0;
+ ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
+}
+
static void
slapd_close( ber_socket_t s )
{
{
int l;
time_t last_idle_check = 0;
- struct timeval idle;
int ebadf = 0;
#define SLAPD_IDLE_CHECK_LIMIT 4
if ( global_idletimeout > 0 ) {
last_idle_check = slap_get_time();
- /* Set the select timeout.
- * Don't just truncate, preserve the fractions of
- * seconds to prevent sleeping for zero time.
- */
- idle.tv_sec = global_idletimeout / SLAPD_IDLE_CHECK_LIMIT;
- idle.tv_usec = global_idletimeout - \
- ( idle.tv_sec * SLAPD_IDLE_CHECK_LIMIT );
- idle.tv_usec *= 1000000 / SLAPD_IDLE_CHECK_LIMIT;
- } else {
- idle.tv_sec = 0;
- idle.tv_usec = 0;
}
slapd_add( wake_sds[0], 0, NULL );
now = slap_get_time();
- if ( ( global_idletimeout > 0 ) &&
- difftime( last_idle_check +
- global_idletimeout/SLAPD_IDLE_CHECK_LIMIT, now ) < 0 )
- {
- connections_timeout_idle( now );
- last_idle_check = now;
+ if ( global_idletimeout > 0 || chk_writetime ) {
+ 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 = global_writetimeout;
+ 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 );
+ tv.tv_usec *= 1000000 / SLAPD_IDLE_CHECK_LIMIT;
+ if ( difftime( last_idle_check +
+ global_idletimeout/SLAPD_IDLE_CHECK_LIMIT, now ) < 0 )
+ check = 1;
+ }
+ if ( check ) {
+ connections_timeout_idle( now );
+ last_idle_check = now;
+ }
+ } else {
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
}
- tv = idle;
#ifdef SIGHUP
if ( slapd_gentle_shutdown ) {
LDAP_SLAPD_F (void) slapd_clr_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 (void) slapd_clr_writetime LDAP_P((time_t old));
+LDAP_SLAPD_F (time_t) slapd_get_writetime LDAP_P((void));
LDAP_SLAPD_V (volatile sig_atomic_t) slapd_abrupt_shutdown;
LDAP_SLAPD_V (volatile sig_atomic_t) slapd_shutdown;
LDAP_SLAPD_V (int) global_gentlehup;
LDAP_SLAPD_V (int) global_idletimeout;
+LDAP_SLAPD_V (int) global_writetimeout;
LDAP_SLAPD_V (char *) global_host;
LDAP_SLAPD_V (char *) global_realm;
LDAP_SLAPD_V (char *) sasl_host;
/* wait for socket to be write-ready */
ldap_pvt_thread_mutex_lock( &conn->c_write2_mutex );
conn->c_writewaiter = 1;
- slapd_set_write( conn->c_sd, 1 );
+ slapd_set_write( conn->c_sd, 2 );
ldap_pvt_thread_mutex_unlock( &conn->c_write1_mutex );
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );