]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/connection.c
streamline group attr specification/diagnostics
[openldap] / servers / slapd / connection.c
index 4534075be1b80ed802a9bdb8f2c91d0d14fec399..eecf90409b9cb09c3cf6ed5179cb9609d6463704 100644 (file)
@@ -1,7 +1,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2006 The OpenLDAP Foundation.
+ * Copyright 1998-2007 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -196,20 +196,22 @@ int connections_shutdown(void)
        ber_socket_t i;
 
        for ( i = 0; i < dtblsize; i++ ) {
-               ldap_pvt_thread_mutex_lock( &connections[i].c_mutex );
-               if( connections[i].c_struct_state == SLAP_C_USED ) {
-
-                       /* give persistent clients a chance to cleanup */
-                       if( connections[i].c_conn_state == SLAP_C_CLIENT ) {
-                               ldap_pvt_thread_pool_submit( &connection_pool,
-                               connections[i].c_clientfunc, connections[i].c_clientarg );
-                       } else {
-                               /* c_mutex is locked */
-                               connection_closing( &connections[i], "slapd shutdown" );
-                               connection_close( &connections[i] );
+               if( connections[i].c_struct_state != SLAP_C_UNINITIALIZED ) {
+                       ldap_pvt_thread_mutex_lock( &connections[i].c_mutex );
+                       if( connections[i].c_struct_state == SLAP_C_USED ) {
+
+                               /* give persistent clients a chance to cleanup */
+                               if( connections[i].c_conn_state == SLAP_C_CLIENT ) {
+                                       ldap_pvt_thread_pool_submit( &connection_pool,
+                                       connections[i].c_clientfunc, connections[i].c_clientarg );
+                               } else {
+                                       /* c_mutex is locked */
+                                       connection_closing( &connections[i], "slapd shutdown" );
+                                       connection_close( &connections[i] );
+                               }
                        }
+                       ldap_pvt_thread_mutex_unlock( &connections[i].c_mutex );
                }
-               ldap_pvt_thread_mutex_unlock( &connections[i].c_mutex );
        }
 
        return 0;
@@ -308,6 +310,15 @@ static Connection* connection_get( ber_socket_t s )
                assert( c->c_struct_state != SLAP_C_UNINITIALIZED );
 
                ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_GET_FD, &sd );
+#ifdef HAVE_WINSOCK
+               /* Avoid race condition after releasing
+                * connections_mutex
+                */
+               if ( sd != s ) {
+                       ldap_pvt_thread_mutex_unlock( &c->c_mutex );
+                       return NULL;
+               }
+#endif
                if( c->c_struct_state != SLAP_C_USED ) {
                        /* connection must have been closed due to resched */
 
@@ -1516,11 +1527,11 @@ connection_input( Connection *conn )
 
                ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_GET_FD, &sd );
 
-               Debug( LDAP_DEBUG_TRACE,
-                       "ber_get_next on fd %d failed errno=%d (%s)\n",
-                       sd, err, sock_errstr(err) );
                if ( err != EWOULDBLOCK && err != EAGAIN ) {
                        /* log, close and send error */
+                       Debug( LDAP_DEBUG_TRACE,
+                               "ber_get_next on fd %d failed errno=%d (%s)\n",
+                       sd, err, sock_errstr(err) );
                        ber_free( conn->c_currentber, 1 );
                        conn->c_currentber = NULL;