]> git.sur5r.net Git - openldap/commitdiff
ITS#6276
authorQuanah Gibson-Mount <quanah@openldap.org>
Sat, 29 Aug 2009 00:39:44 +0000 (00:39 +0000)
committerQuanah Gibson-Mount <quanah@openldap.org>
Sat, 29 Aug 2009 00:39:44 +0000 (00:39 +0000)
CHANGES
servers/slapd/connection.c

diff --git a/CHANGES b/CHANGES
index 840b7bedd13d8300b769083d79c4d972ccd39347..c237f3c1cdd08daafb545b0c1a569551b6775a25 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -10,6 +10,7 @@ OpenLDAP 2.4.18 Engineering
        Added slapd tcp buffers support (ITS#6234)
        Fixed slapd allow mirrormode to be set to FALSE (ITS#5946)
        Fixed slapd certificate list parsing (ITS#6241)
+       Fixed slapd writers blocking (ITS#6276)
        Fixed slapd dncachesize behavior to unlimited by default (ITS#6222)
        Fixed slapd incorrectly applying writetimeout when not set (ITS#6220)
        Fixed slapd with duplicate empty lines for olcDbConfig (ITS#6240)
index b8c7cf05d7fb68ee1f05d83ab83dc6b5072a7387..e1f651bd2b8aea769d8c98d741ff906fd16e596c 100644 (file)
@@ -753,6 +753,32 @@ static void connection_abandon( Connection *c )
        }
 }
 
+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 );
@@ -777,26 +803,7 @@ void connection_closing( Connection *c, const char *why )
                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. */
@@ -1270,6 +1277,11 @@ int connection_read_activate( ber_socket_t s )
        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 );