X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fresult.c;h=353edc99820600722153d2dfef30324d94f3fab9;hb=e9f1452624c7fc828d45ebc1f3cc6fcdf03991db;hp=e0800f4ffc59fb7c3256f692f7ab3ae58afbc0ea;hpb=4908009ed3c58c02df77d9e2b9ab12b82206281c;p=openldap diff --git a/servers/slapd/result.c b/servers/slapd/result.c index e0800f4ffc..353edc9982 100644 --- a/servers/slapd/result.c +++ b/servers/slapd/result.c @@ -139,40 +139,46 @@ static long send_ldap_ber( Connection *conn = op->o_conn; ber_len_t bytes; long ret = 0; - int closing = 0; ber_get_option( ber, LBER_OPT_BER_BYTES_TO_WRITE, &bytes ); /* write only one pdu at a time - wait til it's our turn */ ldap_pvt_thread_mutex_lock( &conn->c_write1_mutex ); - if ( op->o_abandon || connection_state_closing( conn )) { + if (( op->o_abandon && !op->o_cancel ) || !connection_valid( conn ) || + conn->c_writers < 0 ) { ldap_pvt_thread_mutex_unlock( &conn->c_write1_mutex ); return 0; } - while ( conn->c_writers > 0 ) { + + conn->c_writers++; + + while ( conn->c_writers > 0 && conn->c_writing ) { ldap_pvt_thread_cond_wait( &conn->c_write1_cv, &conn->c_write1_mutex ); } + /* connection was closed under us */ if ( conn->c_writers < 0 ) { - closing = 1; /* we're the last waiter, let the closer continue */ if ( conn->c_writers == -1 ) ldap_pvt_thread_cond_signal( &conn->c_write1_cv ); - } - - conn->c_writers++; - - if ( closing ) { + conn->c_writers++; ldap_pvt_thread_mutex_unlock( &conn->c_write1_mutex ); return 0; } + /* Our turn */ + conn->c_writing = 1; + /* write the pdu */ while( 1 ) { int err; /* lock the connection */ if ( ldap_pvt_thread_mutex_trylock( &conn->c_mutex )) { + if ( !connection_valid(conn)) { + ret = 0; + break; + } ldap_pvt_thread_mutex_unlock( &conn->c_write1_mutex ); ldap_pvt_thread_mutex_lock( &conn->c_write1_mutex ); if ( conn->c_writers < 0 ) { @@ -201,6 +207,7 @@ static long send_ldap_ber( if ( err != EWOULDBLOCK && err != EAGAIN ) { conn->c_writers--; + conn->c_writing = 0; ldap_pvt_thread_mutex_unlock( &conn->c_write1_mutex ); connection_closing( conn, "connection lost on write" ); @@ -225,6 +232,7 @@ static long send_ldap_ber( } } + conn->c_writing = 0; if ( conn->c_writers < 0 ) { conn->c_writers++; if ( !conn->c_writers ) @@ -294,11 +302,11 @@ send_ldap_controls( Operation *o, BerElement *ber, LDAPControl **c ) ber_printf( sber, "{e}", LDAP_UNWILLING_TO_PERFORM ); - if( ber_flatten2( ber, &sorted.ldctl_value, 0 ) == -1 ) { + if( ber_flatten2( sber, &sorted.ldctl_value, 0 ) == -1 ) { return -1; } - (void) ber_free_buf( ber ); + (void) ber_free_buf( sber ); rc = send_ldap_control( ber, &sorted ); if( rc == -1 ) return rc; @@ -415,7 +423,7 @@ send_ldap_response( int rc = LDAP_SUCCESS; long bytes; - if ( rs->sr_err == SLAPD_ABANDON || op->o_abandon ) { + if (( rs->sr_err == SLAPD_ABANDON || op->o_abandon ) && !op->o_cancel ) { rc = SLAPD_ABANDON; goto clean2; } @@ -437,9 +445,13 @@ send_ldap_response( ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); } + rc = rs->sr_err; + if ( rc == SLAPD_ABANDON && op->o_cancel ) + rc = LDAP_CANCELLED; + Debug( LDAP_DEBUG_TRACE, "send_ldap_response: msgid=%d tag=%lu err=%d\n", - rs->sr_msgid, rs->sr_tag, rs->sr_err ); + rs->sr_msgid, rs->sr_tag, rc ); if( rs->sr_ref ) { Debug( LDAP_DEBUG_ARGS, "send_ldap_response: ref=\"%s\"\n", @@ -452,7 +464,7 @@ send_ldap_response( op->o_protocol == LDAP_VERSION2 ) { rc = ber_printf( ber, "t{ess" /*"}"*/, - rs->sr_tag, rs->sr_err, + rs->sr_tag, rc, rs->sr_matched == NULL ? "" : rs->sr_matched, rs->sr_text == NULL ? "" : rs->sr_text ); } else @@ -463,7 +475,7 @@ send_ldap_response( } else { rc = ber_printf( ber, "{it{ess" /*"}}"*/, - rs->sr_msgid, rs->sr_tag, rs->sr_err, + rs->sr_msgid, rs->sr_tag, rc, rs->sr_matched == NULL ? "" : rs->sr_matched, rs->sr_text == NULL ? "" : rs->sr_text ); } @@ -604,6 +616,7 @@ send_ldap_disconnect( Operation *op, SlapReply *rs ) assert( LDAP_UNSOLICITED_ERROR( rs->sr_err ) ); rs->sr_type = REP_EXTENDED; + rs->sr_rspdata = NULL; Debug( LDAP_DEBUG_TRACE, "send_ldap_disconnect %d:%s\n", @@ -1665,4 +1678,3 @@ slap_attr_flags( AttributeName *an ) return flags; } -