Re: [PATCH 1/4] IPC: reference count the connection whilst flushing the outq

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 31/01/12 14:49 -0700, Steven Dake wrote:
Which problem does this fix?
1) blast a lot of events at a client
2) the client exits
3) we now have an outstanding job to flush the outq
   but the connection would have been removed.
   So this patch increments the reference count
   when we add the flush job to prevent the mem violation.
4) the flushing function can see that the connection
   is dead and frees up the connection by calling
   qb_ipcs_connection_unref()

-Angus

Reviewed-by: Steven Dake <sdake@xxxxxxxxxx>

On 01/29/2012 08:12 PM, Angus Salkeld wrote:
Signed-off-by: Angus Salkeld <asalkeld@xxxxxxxxxx>
---
 exec/ipc_glue.c |   19 +++++++++++++------
 1 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/exec/ipc_glue.c b/exec/ipc_glue.c
index 67e3a05..2a04495 100644
--- a/exec/ipc_glue.c
+++ b/exec/ipc_glue.c
@@ -497,9 +497,15 @@ static void outq_flush (void *data)
 		outq_item = list_entry (list, struct outq_item, list);

 		rc = qb_ipcs_event_send(conn, outq_item->msg, outq_item->mlen);
-		if (rc != outq_item->mlen) {
+		if (rc < 0 && rc != -EAGAIN) {
+			errno = -rc;
+			qb_perror(LOG_ERR, "qb_ipcs_event_send");
+			qb_ipcs_connection_unref(conn);
+			return;
+		} else if (rc == -EAGAIN) {
 			break;
 		}
+		assert(rc == outq_item->mlen);
 		context->sent++;
 		context->queued--;

@@ -513,11 +519,9 @@ static void outq_flush (void *data)
 			context->queued, context->sent);
 		context->queued = 0;
 		context->sent = 0;
-		return;
-	}
-	qb_loop_job_add(cs_poll_handle_get(), QB_LOOP_HIGH, conn, outq_flush);
-	if (rc < 0 && rc != -EAGAIN) {
-		log_printf(LOGSYS_LEVEL_ERROR, "event_send retuned %d!", rc);
+		qb_ipcs_connection_unref(conn);
+	} else {
+		qb_loop_job_add(cs_poll_handle_get(), QB_LOOP_HIGH, conn, outq_flush);
 	}
 }

@@ -545,6 +549,7 @@ static void msg_send_or_queue(qb_ipcs_connection_t *conn, const struct iovec *io
 			context->queued = 0;
 			context->sent = 0;
 			context->queuing = QB_TRUE;
+			qb_ipcs_connection_ref(conn);
 			qb_loop_job_add(cs_poll_handle_get(), QB_LOOP_HIGH, conn, outq_flush);
 		} else {
 			log_printf(LOGSYS_LEVEL_ERROR, "event_send retuned %d, expected %d!", rc, bytes_msg);
@@ -553,12 +558,14 @@ static void msg_send_or_queue(qb_ipcs_connection_t *conn, const struct iovec *io
 	}
 	outq_item = malloc (sizeof (struct outq_item));
 	if (outq_item == NULL) {
+		qb_ipcs_connection_unref(conn);
 		qb_ipcs_disconnect(conn);
 		return;
 	}
 	outq_item->msg = malloc (bytes_msg);
 	if (outq_item->msg == NULL) {
 		free (outq_item);
+		qb_ipcs_connection_unref(conn);
 		qb_ipcs_disconnect(conn);
 		return;
 	}

_______________________________________________
discuss mailing list
discuss@xxxxxxxxxxxx
http://lists.corosync.org/mailman/listinfo/discuss


[Index of Archives]     [Linux Clusters]     [Corosync Project]     [Linux USB Devel]     [Linux Audio Users]     [Photo]     [Yosemite News]    [Yosemite Photos]    [Linux Kernel]     [Linux SCSI]     [X.Org]

  Powered by Linux