#endif /* LDAP_TCP_BUFFER */
Listener **slap_listeners = NULL;
+static volatile sig_atomic_t listening = 1; /* 0 when slap_listeners closed */
#ifndef SLAPD_LISTEN_BACKLOG
#define SLAPD_LISTEN_BACKLOG 1024
* the select() loop. Now that we're removing a session from our
* control, we can try to resume a dropped listener to use.
*/
- if ( emfile ) {
+ if ( emfile && listening ) {
int i;
for ( i = 0; slap_listeners[i] != NULL; i++ ) {
Listener *lr = slap_listeners[i];
{
int l;
+ if ( !listening )
+ return;
+ listening = 0;
+
for ( l = 0; slap_listeners[l] != NULL; l++ ) {
Listener *lr = slap_listeners[l];
- slap_listeners[l] = NULL;
if ( lr->sl_sd != AC_SOCKET_INVALID ) {
int s = lr->sl_sd;
slapd_close( s );
}
+ }
+}
+
+static void
+destroy_listeners( void )
+{
+ Listener *lr, **ll = slap_listeners;
+
+ if ( ll == NULL )
+ return;
+ while ( (lr = *ll++) != NULL ) {
if ( lr->sl_url.bv_val ) {
ber_memfree( lr->sl_url.bv_val );
}
free( lr );
}
+
+ free( slap_listeners );
+ slap_listeners = NULL;
}
static int
nwriters = slap_daemon[tid].sd_nwriters;
+ if ( listening )
for ( l = 0; slap_listeners[l] != NULL; l++ ) {
Listener *lr = slap_listeners[l];
* true for Unix select and poll. We treat Windows select
* like this too, even though it's a kludge.
*/
+ if ( listening )
for ( l = 0; slap_listeners[l] != NULL; l++ ) {
int rc;
0, 0, 0 );
}
- if ( slapd_gentle_shutdown != 2 ) close_listeners ( 0 );
+ close_listeners( 0 );
if ( !slapd_gentle_shutdown ) {
slapd_abrupt_shutdown = 1;
}
ldap_pvt_thread_pool_destroy( &connection_pool, 1 );
- free( slap_listeners );
- slap_listeners = NULL;
-
return NULL;
}
for ( i=0; i<slapd_daemon_threads; i++ )
ldap_pvt_thread_join( listener_tid[i], (void *)NULL );
+ destroy_listeners();
ch_free( listener_tid );
return 0;
Listener **
slapd_get_listeners( void )
{
+ /* Could return array with no listeners if !listening, but current
+ * callers mostly look at the URLs. E.g. syncrepl uses this to
+ * identify the server, which means it wants the startup arguments.
+ */
return slap_listeners;
}