static Connection* connection_get( int s );
static int connection_input( Connection *c );
+static void connection_close( Connection *c );
static int connection_op_activate( Connection *conn, Operation *op );
static int connection_resched( Connection *conn );
assert( connections == NULL );
- if( connections != NULL) { /* probably should assert this */
+ if( connections != NULL) {
Debug( LDAP_DEBUG_ANY, "connections_init: already initialized.\n",
0, 0, 0 );
return -1;
return 0;
}
+/*
+ * Destroy connection management infrastructure.
+ */
+int connections_destroy(void)
+{
+ int i;
+
+ /* should check return of every call */
+
+ if( connections == NULL) {
+ Debug( LDAP_DEBUG_ANY, "connections_destroy: nothing to destroy.\n",
+ 0, 0, 0 );
+ return -1;
+ }
+
+ for ( i = 0; i < dtblsize; i++ ) {
+ ldap_pvt_thread_mutex_destroy( &connections[i].c_mutex );
+ ldap_pvt_thread_mutex_destroy( &connections[i].c_write_mutex );
+ ldap_pvt_thread_cond_destroy( &connections[i].c_write_cv );
+
+ free( &connections[i] );
+ }
+
+ free( connections );
+ connections = NULL;
+
+ ldap_pvt_thread_mutex_destroy( &connections_mutex );
+ return 0;
+}
+
+/*
+ * shutdown all connections
+ */
+int connections_shutdown(void)
+{
+ int i;
+
+ ldap_pvt_thread_mutex_lock( &connections_mutex );
+
+ for ( i = 0; i < dtblsize; i++ ) {
+ if( connections[i].c_struct_state != SLAP_C_USED ) {
+ continue;
+ }
+
+ ldap_pvt_thread_mutex_lock( &connections[i].c_mutex );
+ connection_closing( &connections[i] );
+ connection_close( &connections[i] );
+ ldap_pvt_thread_mutex_unlock( &connections[i].c_mutex );
+ }
+
+ ldap_pvt_thread_mutex_unlock( &connections_mutex );
+}
+
static Connection* connection_get( int s )
{
Connection *c = NULL;
int connection_state_closing( Connection *c )
{
+ int state;
assert( c != NULL );
assert( c->c_struct_state == SLAP_C_USED );
- assert( c->c_conn_state != SLAP_C_INVALID );
- return c->c_conn_state == SLAP_C_CLOSING;
+ ldap_pvt_thread_mutex_lock( &c->c_mutex );
+ state = c->c_conn_state;
+ ldap_pvt_thread_mutex_unlock( &c->c_mutex );
+
+ assert( state != SLAP_C_INVALID );
+
+ return state == SLAP_C_CLOSING;
}
void connection_closing( Connection *c )
slapd_listener=1;
- connections_init();
-
ldap_pvt_thread_mutex_init( &slap_daemon.sd_mutex );
FD_ZERO( &slap_daemon.sd_readers );
FD_ZERO( &slap_daemon.sd_writers );
tcp_close( tcps );
}
+ /* we only implement "quick" shutdown */
+ connections_shutdown();
+
ldap_pvt_thread_mutex_lock( &active_threads_mutex );
Debug( LDAP_DEBUG_ANY,
"slapd shutdown: waiting for %d threads to terminate\n",
args[0] = inetd;
args[1] = tcps;
+ connections_init();
+
#define SLAPD_LISTENER_THREAD 1
#if SLAPD_LISTENER_THREAD
/* listener as a separate THREAD */
slapd_daemon_task( args );
#endif
+ connections_destroy();
return 0;
}