From bd68f928b710816c984ec3a8dbc852f10ed3f6b4 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sat, 21 Feb 2015 01:49:24 +1100 Subject: [PATCH] Make all one way send_procs asynchronous to avoid message response deadlocks --- src/ckpool.c | 42 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/src/ckpool.c b/src/ckpool.c index 4b753074..989b1b65 100644 --- a/src/ckpool.c +++ b/src/ckpool.c @@ -492,14 +492,32 @@ out: return pid; } -/* Send a single message to a process instance when there will be no response, - * closing the socket immediately. */ -void _send_proc(proc_instance_t *pi, const char *msg, const char *file, const char *func, const int line) +struct proc_message { + proc_instance_t *pi; + char *msg; + const char *file; + const char *func; + int line; +}; + +/* Send all one way messages asynchronously so we can wait till the receiving + * end closes the socket to ensure all messages are received but no deadlocks + * can occur with 2 processes waiting for each other's socket closure. */ +void *async_send_proc(void *arg) { + struct proc_message *pm = (struct proc_message *)arg; + proc_instance_t *pi = pm->pi; + char *msg = pm->msg; + const char *file = pm->file; + const char *func = pm->func; + int line = pm->line; + char *path = pi->us.path; bool ret = false; int sockd; + pthread_detach(pthread_self()); + if (unlikely(!path || !strlen(path))) { LOGERR("Attempted to send message %s to null path in send_proc", msg ? msg : ""); goto out; @@ -533,6 +551,24 @@ out: LOGERR("Failure in send_proc from %s %s:%d", file, func, line); childsighandler(15); } + free(msg); + free(pm); + return NULL; +} + +/* Send a single message to a process instance when there will be no response, + * closing the socket immediately. */ +void _send_proc(proc_instance_t *pi, const char *msg, const char *file, const char *func, const int line) +{ + struct proc_message *pm = ckalloc(sizeof(struct proc_message)); + pthread_t pth; + + pm->pi = pi; + pm->msg = strdup(msg); + pm->file = file; + pm->func = func; + pm->line = line; + create_pthread(&pth, async_send_proc, pm); } /* Send a single message to a process instance and retrieve the response, then