From: Ondřej Kuzník Date: Fri, 22 Sep 2017 10:26:26 +0000 (+0100) Subject: Refactor operation_send_reject X-Git-Tag: OPENLDAP_REL_ENG_2_5_1ALPHA~18^2~113 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0b3531066d73fefc2512656acd9433eec6fa90e9;p=thirdparty%2Fopenldap.git Refactor operation_send_reject --- diff --git a/servers/lloadd/client.c b/servers/lloadd/client.c index 915e90e61d..189f895863 100644 --- a/servers/lloadd/client.c +++ b/servers/lloadd/client.c @@ -67,14 +67,8 @@ handle_one_request( Connection *c ) break; default: if ( c->c_state == SLAP_C_BINDING ) { - op->o_client_refcnt++; - CONNECTION_UNLOCK_INCREF(c); - operation_send_reject( + return operation_send_reject_locked( op, LDAP_PROTOCOL_ERROR, "bind in progress", 0 ); - CONNECTION_LOCK_DECREF(c); - op->o_client_refcnt--; - operation_destroy_from_client( op ); - return LDAP_SUCCESS; } handler = request_process; break; diff --git a/servers/lloadd/operation.c b/servers/lloadd/operation.c index 568f8ea1bd..7b44cfe6f1 100644 --- a/servers/lloadd/operation.c +++ b/servers/lloadd/operation.c @@ -620,11 +620,10 @@ request_abandon( Connection *c, Operation *op ) "connid=%lu msgid=%d invalid integer sent in abandon request\n", c->c_connid, op->o_client_msgid ); - CONNECTION_UNLOCK_INCREF(c); - operation_send_reject( - op, LDAP_PROTOCOL_ERROR, "invalid PDU received", 0 ); - CONNECTION_LOCK_DECREF(c); - CONNECTION_DESTROY(c); + if ( operation_send_reject_locked( op, LDAP_PROTOCOL_ERROR, + "invalid PDU received", 0 ) == LDAP_SUCCESS ) { + CONNECTION_DESTROY(c); + } return -1; } @@ -657,43 +656,27 @@ done: return rc; } -void -operation_send_reject( +/* + * Called with op->o_client non-NULL and already locked. + */ +int +operation_send_reject_locked( Operation *op, int result, const char *msg, int send_anyway ) { - Connection *c; + Connection *c = op->o_client; BerElement *ber; int found; - Debug( LDAP_DEBUG_TRACE, "operation_send_reject: " + Debug( LDAP_DEBUG_TRACE, "operation_send_reject_locked: " "rejecting %s from client connid=%lu with message: \"%s\"\n", - slap_msgtype2str( op->o_tag ), op->o_client_connid, msg ); - - ldap_pvt_thread_mutex_lock( &op->o_link_mutex ); - c = op->o_client; - if ( !c ) { - c = op->o_upstream; - /* One of the connections has initiated this and keeps a reference, if - * client is dead, it must have been the upstream */ - assert( c ); - CONNECTION_LOCK(c); - ldap_pvt_thread_mutex_unlock( &op->o_link_mutex ); - Debug( LDAP_DEBUG_TRACE, "operation_send_reject: " - "not sending msgid=%d, client connid=%lu is dead\n", - op->o_client_msgid, op->o_client_connid ); - operation_destroy_from_upstream( op ); - CONNECTION_UNLOCK_OR_DESTROY(c); - return; - } - CONNECTION_LOCK(c); - ldap_pvt_thread_mutex_unlock( &op->o_link_mutex ); + slap_msgtype2str( op->o_tag ), c->c_connid, msg ); found = ( tavl_delete( &c->c_ops, op, operation_client_cmp ) == op ); if ( !found && !send_anyway ) { - Debug( LDAP_DEBUG_TRACE, "operation_send_reject: " + Debug( LDAP_DEBUG_TRACE, "operation_send_reject_locked: " "msgid=%d not scheduled for client connid=%lu anymore, " "not sending\n", op->o_client_msgid, c->c_connid ); @@ -706,13 +689,13 @@ operation_send_reject( ber = c->c_pendingber; if ( ber == NULL && (ber = ber_alloc()) == NULL ) { ldap_pvt_thread_mutex_unlock( &c->c_io_mutex ); - Debug( LDAP_DEBUG_ANY, "operation_send_reject: " + Debug( LDAP_DEBUG_ANY, "operation_send_reject_locked: " "ber_alloc failed, closing connid=%lu\n", c->c_connid ); CONNECTION_LOCK_DECREF(c); operation_destroy_from_client( op ); CONNECTION_DESTROY(c); - return; + return -1; } c->c_pendingber = ber; @@ -727,7 +710,43 @@ operation_send_reject( CONNECTION_LOCK_DECREF(c); done: operation_destroy_from_client( op ); - CONNECTION_UNLOCK_OR_DESTROY(c); + return LDAP_SUCCESS; +} + +void +operation_send_reject( + Operation *op, + int result, + const char *msg, + int send_anyway ) +{ + Connection *c; + + ldap_pvt_thread_mutex_lock( &op->o_link_mutex ); + c = op->o_client; + if ( !c ) { + c = op->o_upstream; + /* One of the connections has initiated this and keeps a reference, if + * client is dead, it must have been the upstream */ + assert( c ); + CONNECTION_LOCK(c); + ldap_pvt_thread_mutex_unlock( &op->o_link_mutex ); + Debug( LDAP_DEBUG_TRACE, "operation_send_reject: " + "not sending msgid=%d, client connid=%lu is dead\n", + op->o_client_msgid, op->o_client_connid ); + operation_destroy_from_upstream( op ); + CONNECTION_UNLOCK_OR_DESTROY(c); + return; + } + CONNECTION_LOCK(c); + ldap_pvt_thread_mutex_unlock( &op->o_link_mutex ); + + /* Non-zero return means connection has been unlocked and might be + * destroyed */ + if ( operation_send_reject_locked( op, result, msg, send_anyway ) == + LDAP_SUCCESS ) { + CONNECTION_UNLOCK_OR_DESTROY(c); + } } /* diff --git a/servers/lloadd/proto-slap.h b/servers/lloadd/proto-slap.h index a8a43928f5..83cd1f7dba 100644 --- a/servers/lloadd/proto-slap.h +++ b/servers/lloadd/proto-slap.h @@ -159,6 +159,7 @@ LDAP_SLAPD_F (int) operation_client_cmp( const void *l, const void *r ); LDAP_SLAPD_F (Operation *) operation_init( Connection *c, BerElement *ber ); LDAP_SLAPD_F (void) operation_abandon( Operation *op ); LDAP_SLAPD_F (void) operation_send_reject( Operation *op, int result, const char *msg, int send_anyway ); +LDAP_SLAPD_F (int) operation_send_reject_locked( Operation *op, int result, const char *msg, int send_anyway ); LDAP_SLAPD_F (void) operation_lost_upstream( Operation *op ); LDAP_SLAPD_F (void) operation_destroy_from_client( Operation *op ); LDAP_SLAPD_F (void) operation_destroy_from_upstream( Operation *op );