From: Quanah Gibson-Mount Date: Sat, 6 Jun 2009 00:59:03 +0000 (+0000) Subject: More ITS#6104: mutex-protected check of o_cancel value from other thread X-Git-Tag: OPENLDAP_REL_ENG_2_4_17~52 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=1f0481da8d67bbd99f03b3ab5f3e265510d8de69;p=openldap More ITS#6104: mutex-protected check of o_cancel value from other thread --- diff --git a/servers/slapd/cancel.c b/servers/slapd/cancel.c index 6d27d1756a..935a67b1a1 100644 --- a/servers/slapd/cancel.c +++ b/servers/slapd/cancel.c @@ -134,9 +134,16 @@ int cancel_extop( Operation *op, SlapReply *rs ) } } - while ( (rc = o->o_cancel) == SLAP_CANCEL_REQ ) { - ldap_pvt_thread_yield(); - } + do { + /* Fake a cond_wait with thread_yield, then + * verify the result properly mutex-protected. + */ + while ( o->o_cancel == SLAP_CANCEL_REQ ) + ldap_pvt_thread_yield(); + ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); + rc = o->o_cancel; + ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); + } while ( rc == SLAP_CANCEL_REQ ); if ( rc == SLAP_CANCEL_ACK ) { rc = LDAP_SUCCESS; diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c index bf7f68c1ce..cb818a4a9e 100644 --- a/servers/slapd/connection.c +++ b/servers/slapd/connection.c @@ -1021,7 +1021,7 @@ conn_counter_init( Operation *op, void *ctx ) static void * connection_operation( void *ctx, void *arg_v ) { - int rc = LDAP_OTHER; + int rc = LDAP_OTHER, cancel; Operation *op = arg_v; SlapReply rs = {REP_RESULT}; ber_tag_t tag = op->o_tag; @@ -1125,22 +1125,29 @@ operations_error: INCR_OP_COMPLETED( opidx ); } - if ( op->o_cancel == SLAP_CANCEL_REQ ) { - if ( rc == SLAPD_ABANDON ) { - op->o_cancel = SLAP_CANCEL_ACK; - } else { - op->o_cancel = LDAP_TOO_LATE; + ldap_pvt_thread_mutex_lock( &conn->c_mutex ); + + cancel = op->o_cancel; + if ( cancel != SLAP_CANCEL_NONE && cancel != SLAP_CANCEL_DONE ) { + if ( cancel == SLAP_CANCEL_REQ ) { + op->o_cancel = rc == SLAPD_ABANDON + ? SLAP_CANCEL_ACK : LDAP_TOO_LATE; } - } - while ( op->o_cancel != SLAP_CANCEL_NONE && - op->o_cancel != SLAP_CANCEL_DONE ) - { - ldap_pvt_thread_yield(); + do { + /* Fake a cond_wait with thread_yield, then + * verify the result properly mutex-protected. + */ + ldap_pvt_thread_mutex_unlock( &conn->c_mutex ); + do { + ldap_pvt_thread_yield(); + } while ( (cancel = op->o_cancel) != SLAP_CANCEL_NONE + && cancel != SLAP_CANCEL_DONE ); + ldap_pvt_thread_mutex_lock( &conn->c_mutex ); + } while ( (cancel = op->o_cancel) != SLAP_CANCEL_NONE + && cancel != SLAP_CANCEL_DONE ); } - ldap_pvt_thread_mutex_lock( &conn->c_mutex ); - ber_set_option( op->o_ber, LBER_OPT_BER_MEMCTX, &memctx_null ); LDAP_STAILQ_REMOVE( &conn->c_ops, op, Operation, o_next);