From 370ea14149c3cd18262f0b62e349087707d877db Mon Sep 17 00:00:00 2001
From: "benjamin.franksen" <benjamin.franksen@helmholtz-berlin.de>
Date: Fri, 12 Jul 2013 17:10:19 +0000
Subject: [PATCH] seq: place program lock around wakeup commands in ca callback

This prevents a race condition resulting in a crash when the program
shuts down and deletes mutexes etc before the callback has issued its
final ss_wakeup call.
---
 src/seq/seq_ca.c | 30 +++++++++++++++++-------------
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/src/seq/seq_ca.c b/src/seq/seq_ca.c
index 1ffccc84..29b1c696 100644
--- a/src/seq/seq_ca.c
+++ b/src/seq/seq_ca.c
@@ -305,21 +305,23 @@ static void proc_db_events(
 			   Set the dirty flag only if this was a monitor event. */
 			ss_write_buffer(ch, val, &meta, evtype == pvEventMonitor);
 		}
+	}
+
+	epicsMutexMustLock(sp->programLock);
 
-		/* Signal completion */
-		if (ss)
+	/* Signal completion */
+	if (ss)
+	{
+		switch (evtype)
 		{
-			switch (evtype)
-			{
-			case pvEventGet:
-				epicsEventSignal(ss->getSemId[chNum(ch)]);
-				break;
-			case pvEventPut:
-				epicsEventSignal(ss->putSemId[chNum(ch)]);
-				break;
-			default:
-				break;
-			}
+		case pvEventGet:
+			epicsEventSignal(ss->getSemId[chNum(ch)]);
+			break;
+		case pvEventPut:
+			epicsEventSignal(ss->putSemId[chNum(ch)]);
+			break;
+		default:
+			break;
 		}
 	}
 
@@ -329,6 +331,8 @@ static void proc_db_events(
 
 	/* Wake up each state set that uses this channel in an event */
 	ss_wakeup(sp, ch->eventNum);
+
+	epicsMutexUnlock(sp->programLock);
 }
 
 /* Disconnect all database channels */
-- 
GitLab