From 6da3ca027333c3443bc9c07abbeef4e1b45644b9 Mon Sep 17 00:00:00 2001
From: "ben.franksen" <ben.franksen@online.de>
Date: Thu, 31 Mar 2011 17:55:56 +0000
Subject: [PATCH] seq: move locking inwards in anonymous_put

---
 src/seq/seq_if.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/src/seq/seq_if.c b/src/seq/seq_if.c
index 8e4d48bf..6c6d687d 100644
--- a/src/seq/seq_if.c
+++ b/src/seq/seq_if.c
@@ -202,8 +202,6 @@ static void anonymous_put(SS_ID ss, CHAN *ch)
 {
 	char *var = valPtr(ch,ss);
 
-	/* Must lock because multiple writers */
-	epicsMutexMustLock(ch->varLock);
 	if (ch->queue)
 	{
 		QUEUE queue = ch->queue;
@@ -215,6 +213,12 @@ static void anonymous_put(SS_ID ss, CHAN *ch)
 		DEBUG("anonymous_put: type=%d, size=%d, count=%d, buf_size=%d, q=%p\n",
 			type, size, ch->count, pv_size_n(type, ch->count), queue);
 		print_channel_value(DEBUG, ch, var);
+
+		/* Note: Must lock here because multiple state sets can issue
+		   pvPut calls concurrently. OTOH, no need to lock against CA
+		   callbacks, because anonymous and named PVs are disjoint. */
+		epicsMutexMustLock(ch->varLock);
+
 		memcpy(pv_value_ptr(value, type), var, size * ch->count);
 		print_channel_value(DEBUG, ch, pv_value_ptr(value, type));
 		/* Copy whole message into queue */
@@ -227,14 +231,14 @@ static void anonymous_put(SS_ID ss, CHAN *ch)
 			  ch->varName
 			);
 		}
+
+		epicsMutexUnlock(ch->varLock);
 	}
 	/* check if monitored to mirror behaviour for named PVs */
 	else if (ch->monitored)
 	{
 		ss_write_buffer(ch, var, 0);
 	}
-	/* Must give varLock before calling seq_efSet, else (possible) deadlock! */
-	epicsMutexUnlock(ch->varLock);
 	/* Wake up each state set that uses this channel in an event */
 	seqWakeup(ss->sprog, ch->eventNum);
 	/* If there's an event flag associated with this channel, set it */
-- 
GitLab