c != NULL;
c = connection_next( c, &connindex ) )
{
- /* Don't timeout a slow-running request */
- if( c->c_n_ops_executing ) continue;
+ /* Don't timeout a slow-running request or a persistent
+ * outbound connection */
+ if( c->c_n_ops_executing ||
+ c->c_conn_state == SLAP_C_CLIENT ) continue;
if( difftime( c->c_activitytime+global_idletimeout, now) < 0 ) {
/* close it */
ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_GET_FD, &sd );
if ( sd != AC_SOCKET_INVALID ) {
- slapd_remove( sd, 0 );
+ slapd_remove( sd, 1, 0 );
Statslog( LDAP_DEBUG_STATS,
"conn=%lu fd=%ld closed\n",
c->c_clientfunc = func;
c->c_clientarg = arg;
connection_return( c );
- slapd_add_internal( s );
+ slapd_add_internal( s, 0 );
slapd_set_read( s, 1 );
return 0;
}
c->c_conn_state = SLAP_C_INVALID;
c->c_struct_state = SLAP_C_UNUSED;
connection_return( c );
+ slapd_remove( s, 0, 0 );
}
int connection_read(ber_socket_t s)
"connection_read(%ld): no connection!\n",
(long) s, 0, 0 );
#endif
- slapd_remove(s, 0);
+ slapd_remove(s, 1, 0);
ldap_pvt_thread_mutex_unlock( &connections_mutex );
return -1;
"connection_write(%ld): no connection!\n",
(long) s, 0, 0 );
#endif
- slapd_remove(s, 0);
+ slapd_remove(s, 1, 0);
ldap_pvt_thread_mutex_unlock( &connections_mutex );
return -1;
}
/*
* Add a descriptor to daemon control
+ *
+ * If isactive, the descriptor is a live server session and is subject
+ * to idletimeout control. Otherwise, the descriptor is a passive
+ * listener or an outbound client session, and not subject to
+ * idletimeout.
*/
-static void slapd_add(ber_socket_t s) {
+static void slapd_add(ber_socket_t s, int isactive) {
ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
assert( !FD_ISSET( s, &slap_daemon.sd_actives ));
}
#endif
- slap_daemon.sd_nactives++;
+ if ( isactive ) {
+ slap_daemon.sd_nactives++;
+ }
FD_SET( s, &slap_daemon.sd_actives );
FD_SET( s, &slap_daemon.sd_readers );
/*
* Remove the descriptor from daemon control
*/
-void slapd_remove(ber_socket_t s, int wake) {
+void slapd_remove(ber_socket_t s, int wasactive, int wake) {
ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
- slap_daemon.sd_nactives--;
+ if ( wasactive ) {
+ slap_daemon.sd_nactives--;
+ }
#ifdef NEW_LOGGING
LDAP_LOG( CONNECTION, DETAIL1,
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 );
+ slapd_remove( slap_listeners[l]->sl_sd, 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 );
* are unnecessary.
*/
if ( slap_listeners[l]->sl_is_udp ) {
- slapd_add( slap_listeners[l]->sl_sd );
+ slapd_add( slap_listeners[l]->sl_sd, 1 );
continue;
}
#endif
return( (void*)-1 );
}
- slapd_add( slap_listeners[l]->sl_sd );
+ slapd_add( slap_listeners[l]->sl_sd, 0 );
}
#ifdef HAVE_NT_SERVICE_MANAGER
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
- if ( !at ) {
- at = ldap_pvt_thread_pool_backload(&connection_pool) -
- ldap_pvt_runqueue_persistent_backload( &syncrepl_rq );
- }
-
if ( at
#if defined(HAVE_YIELDING_SELECT) || defined(NO_THREADS)
&& ( tv.tv_sec || tv.tv_usec )
rtask = ldap_pvt_runqueue_next_sched( &syncrepl_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 );
+ ldap_pvt_runqueue_resched( &syncrepl_rq, rtask, 0 );
} else {
ldap_pvt_runqueue_runtask( &syncrepl_rq, rtask );
- ldap_pvt_runqueue_resched( &syncrepl_rq, rtask );
+ ldap_pvt_runqueue_resched( &syncrepl_rq, rtask, 0 );
ldap_pvt_thread_mutex_unlock( &syncrepl_rq.rq_mutex );
ldap_pvt_thread_pool_submit( &connection_pool,
rtask->routine, (void *) rtask );
slap_listeners[l]->sl_name.bv_val,
0 );
- slapd_add( s );
+ slapd_add( s, 1 );
continue;
}
}
-void slapd_add_internal(ber_socket_t s) {
- slapd_add(s);
+void slapd_add_internal(ber_socket_t s, int isactive) {
+ slapd_add(s, isactive);
}
Listener ** slapd_get_listeners(void) {
/*
* daemon.c
*/
-LDAP_SLAPD_F (void) slapd_add_internal(ber_socket_t s);
+LDAP_SLAPD_F (void) slapd_add_internal(ber_socket_t s, int isactive);
LDAP_SLAPD_F (int) slapd_daemon_init( const char *urls );
LDAP_SLAPD_F (int) slapd_daemon_destroy(void);
LDAP_SLAPD_F (int) slapd_daemon(void);
LDAP_SLAPD_F (Listener **) slapd_get_listeners LDAP_P((void));
-LDAP_SLAPD_F (void) slapd_remove LDAP_P((ber_socket_t s, int wake));
+LDAP_SLAPD_F (void) slapd_remove LDAP_P((ber_socket_t s, int wasactive, int wake));
LDAP_SLAPD_F (RETSIGTYPE) slap_sig_shutdown LDAP_P((int sig));
LDAP_SLAPD_F (RETSIGTYPE) slap_sig_wake LDAP_P((int sig));
} else {
connection_client_enable( s );
}
- /* Don't need to resched this task for a while */
- if ( rc == 0 ) rc = 1;
} else {
connection_client_stop( s );
}
}
}
- if ( rc == LDAP_SUCCESS || rc == LDAP_SERVER_DOWN ) {
- ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex );
+ /* At this point, we have 4 cases:
+ * 1) for any hard failure, give up and remove this task
+ * 2) for ServerDown, reschedule this task to run
+ * 3) for Refresh and Success, reschedule to run
+ * 4) for Persist and Success, reschedule to defer
+ */
+ ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex );
+ if ( ldap_pvt_runqueue_isrunning( &syncrepl_rq, rtask )) {
ldap_pvt_runqueue_stoptask( &syncrepl_rq, rtask );
- ldap_pvt_runqueue_resched( &syncrepl_rq, rtask );
- ldap_pvt_thread_mutex_unlock( &syncrepl_rq.rq_mutex );
}
+ if ( rc && rc != LDAP_SERVER_DOWN ) {
+ ldap_pvt_runqueue_remove( &syncrepl_rq, rtask );
+ } else if ( rc == LDAP_SERVER_DOWN ||
+ si->si_type == LDAP_SYNC_REFRESH_ONLY ) {
+ rc = 0;
+ } else {
+ rc = 1;
+ }
+ ldap_pvt_runqueue_resched( &syncrepl_rq, rtask, rc );
+ ldap_pvt_thread_mutex_unlock( &syncrepl_rq.rq_mutex );
+
return NULL;
}