]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/operation.c
hack for #6982 - keep o_abandon set in op_free
[openldap] / servers / slapd / operation.c
index e975eae28d3bb152ff88dfa684346601d1de08b3..f808320501e3d52d870e2b8487be728ec079f9e6 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2008 The OpenLDAP Foundation.
+ * Copyright 1998-2011 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -111,16 +111,41 @@ slap_op_free( Operation *op, void *ctx )
        }
 #endif /* defined( LDAP_SLAPI ) */
 
+       if ( !BER_BVISNULL( &op->o_csn ) ) {
+               op->o_tmpfree( op->o_csn.bv_val, op->o_tmpmemctx );
+       }
+
+       if ( op->o_pagedresults_state != NULL ) {
+               op->o_tmpfree( op->o_pagedresults_state, op->o_tmpmemctx );
+       }
+
+       /* Selectively zero out the struct. Ignore fields that will
+        * get explicitly initialized later anyway. Keep o_abandon intact.
+        */
        opbuf = (OperationBuffer *) op;
-       memset( opbuf, 0, sizeof(*opbuf) );
-       op->o_hdr = &opbuf->ob_hdr;
+       op->o_bd = NULL;
+       BER_BVZERO( &op->o_req_dn );
+       BER_BVZERO( &op->o_req_ndn );
+       memset( &op->o_request, 0, sizeof( op->o_request ));
+       memset( &op->o_do_not_cache, 0, sizeof( Operation ) - offsetof( Operation, o_do_not_cache ));
        op->o_controls = opbuf->ob_controls;
 
        if ( ctx ) {
-               void *op2 = NULL;
+               Operation *op2 = NULL;
                ldap_pvt_thread_pool_setkey( ctx, (void *)slap_op_free,
-                       op, slap_op_q_destroy, &op2, NULL );
+                       op, slap_op_q_destroy, (void **)&op2, NULL );
                LDAP_STAILQ_NEXT( op, o_next ) = op2;
+               if ( op2 ) {
+                       op->o_tincr = op2->o_tincr + 1;
+                       /* No more than 10 ops on per-thread free list */
+                       if ( op->o_tincr > 10 ) {
+                               ldap_pvt_thread_pool_setkey( ctx, (void *)slap_op_free,
+                                       op2, slap_op_q_destroy, NULL, NULL );
+                               ber_memfree_x( op, NULL );
+                       }
+               } else {
+                       op->o_tincr = 1;
+               }
        } else {
                ber_memfree_x( op, NULL );
        }
@@ -129,8 +154,8 @@ slap_op_free( Operation *op, void *ctx )
 void
 slap_op_time(time_t *t, int *nop)
 {
-       *t = slap_get_time();
        ldap_pvt_thread_mutex_lock( &slap_op_mutex );
+       *t = slap_get_time();
        if ( *t == last_time ) {
                *nop = ++last_incr;
        } else {
@@ -159,6 +184,8 @@ slap_op_alloc(
                        otmp = LDAP_STAILQ_NEXT( op, o_next );
                        ldap_pvt_thread_pool_setkey( ctx, (void *)slap_op_free,
                                otmp, slap_op_q_destroy, NULL, NULL );
+                       op->o_abandon = 0;
+                       op->o_cancel = 0;
                }
        }
        if (!op) {
@@ -173,7 +200,6 @@ slap_op_alloc(
 
        slap_op_time( &op->o_time, &op->o_tincr );
        op->o_opid = id;
-       op->o_res_ber = NULL;
 
 #if defined( LDAP_SLAPI )
        if ( slapi_plugins_used ) {