X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fconnection.c;h=4662f98cebd5be4c03af22fdc0985f9fe527081a;hb=dbaf7c5c2503b2770c9075e30a9a63b6ff577d6f;hp=f989d8ddaac734b09dccc83b63631f37553d3428;hpb=da6a4bcd3e44aad30d4278fb4f7610582799b967;p=openldap diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c index f989d8ddaa..4662f98ceb 100644 --- a/servers/slapd/connection.c +++ b/servers/slapd/connection.c @@ -829,9 +829,19 @@ void connection_closing( Connection *c, const char *why ) connection_abandon( c ); /* wake write blocked operations */ - slapd_clr_write( sd, 1 ); if ( c->c_writewaiter ) { ldap_pvt_thread_cond_signal( &c->c_write_cv ); + /* ITS#4667 this may allow another thread to drop into + * connection_resched / connection_close before we + * finish, but that's OK. + */ + slapd_clr_write( sd, 1 ); + ldap_pvt_thread_mutex_unlock( &c->c_mutex ); + ldap_pvt_thread_mutex_lock( &c->c_write_mutex ); + ldap_pvt_thread_mutex_lock( &c->c_mutex ); + ldap_pvt_thread_mutex_unlock( &c->c_write_mutex ); + } else { + slapd_clr_write( sd, 1 ); } } else if( why == NULL && c->c_close_reason == conn_lost_str ) { @@ -847,6 +857,11 @@ connection_close( Connection *c ) assert( connections != NULL ); assert( c != NULL ); + + /* ITS#4667 we may have gotten here twice */ + if ( c->c_conn_state == SLAP_C_INVALID ) + return; + assert( c->c_struct_state == SLAP_C_USED ); assert( c->c_conn_state == SLAP_C_CLOSING ); @@ -917,7 +932,11 @@ Connection* connection_next( Connection *c, ber_socket_t *index ) int c_struct; if( connections[*index].c_struct_state == SLAP_C_UNINITIALIZED ) { assert( connections[*index].c_conn_state == SLAP_C_INVALID ); +#ifdef HAVE_WINSOCK break; +#else + continue; +#endif } if( connections[*index].c_struct_state == SLAP_C_USED ) { @@ -1473,7 +1492,7 @@ connection_input( Connection *conn ) return -1; } - errno = 0; + sock_errset(0); #ifdef LDAP_CONNECTIONLESS if ( conn->c_is_udp ) { @@ -1493,7 +1512,7 @@ connection_input( Connection *conn ) tag = ber_get_next( conn->c_sb, &len, conn->c_currentber ); if ( tag != LDAP_TAG_MESSAGE ) { - int err = errno; + int err = sock_errno(); ber_socket_t sd; ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_GET_FD, &sd );