static Connection *connections = NULL;
static ldap_pvt_thread_mutex_t conn_nextid_mutex;
-static unsigned long conn_nextid = 0;
+static unsigned long conn_nextid = SLAPD_SYNC_SYNCCONN_OFFSET;
static const char conn_lost_str[] = "connection lost";
-/* structure state (protected by connections_mutex) */
-enum sc_struct_state {
- SLAP_C_UNINITIALIZED = 0, /* MUST BE ZERO (0) */
- SLAP_C_UNUSED,
- SLAP_C_USED,
- SLAP_C_PENDING
-};
-
-/* connection state (protected by c_mutex ) */
-enum sc_conn_state {
- SLAP_C_INVALID = 0, /* MUST BE ZERO (0) */
- SLAP_C_INACTIVE, /* zero threads */
- SLAP_C_CLOSING, /* closing */
- SLAP_C_ACTIVE, /* one or more threads */
- SLAP_C_BINDING, /* binding */
- SLAP_C_CLIENT /* outbound client conn */
-};
-
const char *
connection_state2str( int state )
{
}
}
+static void
+connection_wake_writers( Connection *c )
+{
+ /* wake write blocked operations */
+ ldap_pvt_thread_mutex_lock( &c->c_write1_mutex );
+ if ( c->c_writers > 0 ) {
+ c->c_writers = -c->c_writers;
+ ldap_pvt_thread_cond_broadcast( &c->c_write1_cv );
+ ldap_pvt_thread_mutex_unlock( &c->c_write1_mutex );
+ if ( c->c_writewaiter ) {
+ ldap_pvt_thread_mutex_lock( &c->c_write2_mutex );
+ ldap_pvt_thread_cond_signal( &c->c_write2_cv );
+ slapd_clr_write( c->c_sd, 1 );
+ ldap_pvt_thread_mutex_unlock( &c->c_write2_mutex );
+ }
+ ldap_pvt_thread_mutex_lock( &c->c_write1_mutex );
+ while ( c->c_writers ) {
+ ldap_pvt_thread_cond_wait( &c->c_write1_cv, &c->c_write1_mutex );
+ }
+ ldap_pvt_thread_mutex_unlock( &c->c_write1_mutex );
+ } else {
+ ldap_pvt_thread_mutex_unlock( &c->c_write1_mutex );
+ slapd_clr_write( c->c_sd, 1 );
+ }
+}
+
void connection_closing( Connection *c, const char *why )
{
assert( connections != NULL );
assert( c != NULL );
- assert( c->c_struct_state == SLAP_C_USED );
+
+ if ( c->c_struct_state != SLAP_C_USED ) return;
+
assert( c->c_conn_state != SLAP_C_INVALID );
/* c_mutex must be locked by caller */
connection_abandon( c );
/* wake write blocked operations */
- ldap_pvt_thread_mutex_lock( &c->c_write1_mutex );
- if ( c->c_writers > 0 ) {
- c->c_writers = -c->c_writers;
- ldap_pvt_thread_cond_broadcast( &c->c_write1_cv );
- ldap_pvt_thread_mutex_unlock( &c->c_write1_mutex );
- if ( c->c_writewaiter ) {
- ldap_pvt_thread_mutex_lock( &c->c_write2_mutex );
- ldap_pvt_thread_cond_signal( &c->c_write2_cv );
- slapd_clr_write( c->c_sd, 1 );
- ldap_pvt_thread_mutex_unlock( &c->c_write2_mutex );
- }
- ldap_pvt_thread_mutex_lock( &c->c_write1_mutex );
- while ( c->c_writers ) {
- ldap_pvt_thread_cond_wait( &c->c_write1_cv, &c->c_write1_mutex );
- }
- ldap_pvt_thread_mutex_unlock( &c->c_write1_mutex );
- } else {
- ldap_pvt_thread_mutex_unlock( &c->c_write1_mutex );
- slapd_clr_write( c->c_sd, 1 );
- }
+ connection_wake_writers( c );
} else if( why == NULL && c->c_close_reason == conn_lost_str ) {
/* Client closed connection after doing Unbind. */
{
assert( connections != NULL );
assert( c != NULL );
- assert( c->c_struct_state == SLAP_C_USED );
+
+ if ( c->c_struct_state != SLAP_C_USED ) return;
+
assert( c->c_conn_state == SLAP_C_CLOSING );
/* NOTE: c_mutex should be locked by caller */
if ( rc )
return rc;
+ /* Don't let blocked writers block a pause request */
+ if ( connections[s].c_writewaiter &&
+ ldap_pvt_thread_pool_pausing( &connection_pool ))
+ connection_wake_writers( &connections[s] );
+
rc = ldap_pvt_thread_pool_submit( &connection_pool,
connection_read_thread, (void *)(long)s );
c->c_connid, (int) s, c->c_tls_ssf, c->c_ssf, 0 );
slap_sasl_external( c, c->c_tls_ssf, &authid );
if ( authid.bv_val ) free( authid.bv_val );
+ } else if ( rc == 1 && ber_sockbuf_ctrl( c->c_sb,
+ LBER_SB_OPT_NEEDS_WRITE, NULL )) { /* need to retry */
+ slapd_set_write( s, 1 );
+ connection_return( c );
+ return 0;
}
/* if success and data is ready, fall thru to data input loop */
return -1;
}
+#ifdef HAVE_TLS
+ if ( c->c_is_tls && c->c_needs_tls_accept ) {
+ connection_return( c );
+ connection_read_activate( s );
+ return 0;
+ }
+#endif
+
c->c_n_write++;
Debug( LDAP_DEBUG_TRACE,