From 163077ec939745a8ea86e0ee2e82423675827379 Mon Sep 17 00:00:00 2001
From: Kurt Zeilenga <kurt@openldap.org>
Date: Fri, 29 Jan 1999 05:46:12 +0000
Subject: [PATCH] Don't leak slap_op when op not in list. Don't leak abandon
 mutex. Use ch_malloc and friends.

---
 servers/slapd/config.c     |  2 +-
 servers/slapd/connection.c | 12 ++++++++----
 servers/slapd/daemon.c     |  4 ++--
 servers/slapd/operation.c  | 13 ++++++++++---
 4 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/servers/slapd/config.c b/servers/slapd/config.c
index 6dcaae3d42..b810460680 100644
--- a/servers/slapd/config.c
+++ b/servers/slapd/config.c
@@ -282,7 +282,7 @@ read_config( char *fname, Backend **bep, FILE *pfp )
 				    fname, lineno, 0 );
 				exit( 1 );
 			}
-			default_referral = (char *) malloc( strlen( cargv[1] )
+			default_referral = (char *) ch_malloc( strlen( cargv[1] )
 			    + sizeof("Referral:\n") + 1 );
 			strcpy( default_referral, "Referral:\n" );
 			strcat( default_referral, cargv[1] );
diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c
index 563d33bd50..e8f09b46c0 100644
--- a/servers/slapd/connection.c
+++ b/servers/slapd/connection.c
@@ -89,9 +89,13 @@ connection_operation( void *arg_v )
 
 	ldap_pvt_thread_mutex_lock( &arg->co_conn->c_opsmutex );
 	arg->co_conn->c_opscompleted++;
+
 	slap_op_delete( &arg->co_conn->c_ops, arg->co_op );
+	arg->co_op = NULL;
+
 	ldap_pvt_thread_mutex_unlock( &arg->co_conn->c_opsmutex );
 
+	arg->co_conn = NULL;
 	free( (char *) arg );
 
 	ldap_pvt_thread_mutex_lock( &ops_mutex );
@@ -195,12 +199,12 @@ connection_activity(
 		free( tmpdn );
 	}
 
+	ldap_pvt_thread_mutex_lock( &active_threads_mutex );
+	active_threads++;
+	ldap_pvt_thread_mutex_unlock( &active_threads_mutex );
+
 	if ( status = ldap_pvt_thread_create( &arg->co_op->o_tid, 1,
 	    connection_operation, (void *) arg ) != 0 ) {
 		Debug( LDAP_DEBUG_ANY, "ldap_pvt_thread_create failed (%d)\n", status, 0, 0 );
-	} else {
-		ldap_pvt_thread_mutex_lock( &active_threads_mutex );
-		active_threads++;
-		ldap_pvt_thread_mutex_unlock( &active_threads_mutex );
 	}
 }
diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c
index 4e2ac8756c..8b40c58faf 100644
--- a/servers/slapd/daemon.c
+++ b/servers/slapd/daemon.c
@@ -358,9 +358,9 @@ slapd_daemon(
 				    "signaling write waiter on %d\n", i, 0, 0 );
 
 				ldap_pvt_thread_mutex_lock( &active_threads_mutex );
-				ldap_pvt_thread_cond_signal( &c[i].c_wcv );
-				c[i].c_writewaiter = 0;
 				active_threads++;
+				c[i].c_writewaiter = 0;
+				ldap_pvt_thread_cond_signal( &c[i].c_wcv );
 				ldap_pvt_thread_mutex_unlock( &active_threads_mutex );
 			}
 
diff --git a/servers/slapd/operation.c b/servers/slapd/operation.c
index bf9590de98..2fff851887 100644
--- a/servers/slapd/operation.c
+++ b/servers/slapd/operation.c
@@ -13,15 +13,20 @@
 void
 slap_op_free( Operation *op )
 {
-	if ( op->o_ber != NULL )
+	ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
+
+	if ( op->o_ber != NULL ) {
 		ber_free( op->o_ber, 1 );
+	}
 	if ( op->o_dn != NULL ) {
 		free( op->o_dn );
 	}
 	if ( op->o_ndn != NULL ) {
 		free( op->o_ndn );
 	}
-	/* ldap_pvt_thread_mutex_destroy( &op->o_abandonmutex ); */
+
+	ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
+	ldap_pvt_thread_mutex_destroy( &op->o_abandonmutex );
 	free( (char *) op );
 }
 
@@ -41,7 +46,8 @@ slap_op_add(
 	for ( tmp = olist; *tmp != NULL; tmp = &(*tmp)->o_next )
 		;	/* NULL */
 
-	*tmp = (Operation *) calloc( 1, sizeof(Operation) );
+	*tmp = (Operation *) ch_calloc( 1, sizeof(Operation) );
+
 	ldap_pvt_thread_mutex_init( &(*tmp)->o_abandonmutex );
 	(*tmp)->o_ber = ber;
 	(*tmp)->o_msgid = msgid;
@@ -72,6 +78,7 @@ slap_op_delete( Operation **olist, Operation *op )
 	if ( *tmp == NULL ) {
 		Debug( LDAP_DEBUG_ANY, "op_delete: can't find op %ld\n",
 		    op->o_msgid, 0, 0 );
+		slap_op_free( op );
 		return; 
 	}
 
-- 
GitLab