]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/overlays/rwm.c
fix ITS#3788: don't free slapo-rwm callback, rather reuse it
[openldap] / servers / slapd / overlays / rwm.c
index b91ba2c17fd670dcdf3a9dd99fd70616f3c0572b..28b9135287c1b2daf0bd1a1c7f2810c99f9f0b0e 100644 (file)
@@ -583,6 +583,42 @@ rwm_op_modrdn( Operation *op, SlapReply *rs )
        return SLAP_CB_CONTINUE;
 }
 
+static slap_callback   *rwm_cb;
+
+static void
+rwm_keyfree(
+       void            *key,
+       void            *data )
+{
+       ber_memfree_x( data, NULL );
+}
+
+static slap_callback *
+rwm_callback_get( Operation *op )
+{
+       void            *data = NULL;
+
+       if ( op->o_threadctx ) {
+               ldap_pvt_thread_pool_getkey( op->o_threadctx,
+                               rwm_keyfree, &data, NULL );
+       } else {
+               data = rwm_cb;
+       }
+
+       if ( data == NULL ) {
+               data = ber_memalloc( sizeof( slap_callback ) );
+               if ( op->o_threadctx ) {
+                       ldap_pvt_thread_pool_setkey( op->o_threadctx,
+                                       rwm_keyfree, data, rwm_keyfree );
+
+               } else {
+                       rwm_cb = (slap_callback *)data;
+               }
+       }
+
+       return (slap_callback *)data;
+}
+
 static int
 rwm_swap_attrs( Operation *op, SlapReply *rs )
 {
@@ -594,18 +630,6 @@ rwm_swap_attrs( Operation *op, SlapReply *rs )
        return SLAP_CB_CONTINUE;
 }
 
-static int rwm_freeself( Operation *op, SlapReply *rs )
-{
-       if ( op->o_tag == LDAP_REQ_SEARCH && rs->sr_type == REP_RESULT ) {
-               assert( op->o_callback );
-
-               op->o_tmpfree( op->o_callback, op->o_tmpmemctx );
-               op->o_callback = NULL;
-       }
-
-       return SLAP_CB_CONTINUE;
-}
-
 static int
 rwm_op_search( Operation *op, SlapReply *rs )
 {
@@ -619,7 +643,7 @@ rwm_op_search( Operation *op, SlapReply *rs )
        struct berval           fstr = BER_BVNULL;
        Filter                  *f = NULL;
 
-       slap_callback           *cb;
+       slap_callback           *cb = NULL;
        AttributeName           *an = NULL;
 
        char                    *text = NULL;
@@ -679,15 +703,10 @@ rwm_op_search( Operation *op, SlapReply *rs )
                goto error_return;
        }
 
-       cb = (slap_callback *) op->o_tmpcalloc( sizeof( slap_callback ),
-                       1, op->o_tmpmemctx );
-       if ( cb == NULL ) {
-               rc = LDAP_NO_MEMORY;
-               goto error_return;
-       }
+       cb = rwm_callback_get( op );
 
        cb->sc_response = rwm_swap_attrs;
-       cb->sc_cleanup = rwm_freeself;
+       cb->sc_cleanup = NULL;
        cb->sc_private = (void *)op->ors_attrs;
        cb->sc_next = op->o_callback;
 
@@ -1045,6 +1064,18 @@ rwm_send_entry( Operation *op, SlapReply *rs )
        return SLAP_CB_CONTINUE;
 
 fail:;
+       if ( e != NULL && e != rs->sr_entry ) {
+               if ( e->e_name.bv_val == dn.bv_val ) {
+                       BER_BVZERO( &e->e_name );
+               }
+
+               if ( e->e_nname.bv_val == ndn.bv_val ) {
+                       BER_BVZERO( &e->e_nname );
+               }
+
+               entry_free( e );
+       }
+
        if ( !BER_BVISNULL( &dn ) ) {
                ch_free( dn.bv_val );
        }
@@ -1053,10 +1084,6 @@ fail:;
                ch_free( ndn.bv_val );
        }
 
-       if ( e != NULL && e != rs->sr_entry ) {
-               entry_free( e );
-       }
-
        return rc;
 }