]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/connection.c
More ldapbis cleanup
[openldap] / servers / slapd / connection.c
index f989d8ddaac734b09dccc83b63631f37553d3428..4662f98cebd5be4c03af22fdc0985f9fe527081a 100644 (file)
@@ -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 );