From f4ca3de8c6a25bb4ea052450f5dd6aec62070939 Mon Sep 17 00:00:00 2001
From: "benjamin.franksen" <benjamin.franksen@helmholtz-berlin.de>
Date: Thu, 1 Mar 2012 13:57:35 +0000
Subject: [PATCH] seq: fixed order of state set wakeup and signalling of
 completions

This was a subtle concurrency bug discovered and analyzed by Lewis Muir:
if pvPutComplete or pvGetComplete are used inside a when-clause, waking
up the state set before signalling completion could result in a deadlock.
---
 src/seq/seq_ca.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/seq/seq_ca.c b/src/seq/seq_ca.c
index 4ebdf24f..2acc6361 100644
--- a/src/seq/seq_ca.c
+++ b/src/seq/seq_ca.c
@@ -253,14 +253,6 @@ static void proc_db_events(
 		ss_write_buffer(ch, val, &meta, evtype == MON_COMPLETE);
 	}
 
-	/* Wake up each state set that uses this channel in an event */
-	seqWakeup(sp, ch->eventNum);
-
-	/* If there's an event flag associated with this channel, set it */
-	/* TODO: check if correct/documented to do this for non-monitor completions */
-	if (ch->efId > 0)
-		seq_efSet(sp->ss, ch->efId);
-
 	/* Signal completion */
 	switch (evtype)
 	{
@@ -273,6 +265,14 @@ static void proc_db_events(
 	default:
 		break;
 	}
+
+	/* If there's an event flag associated with this channel, set it */
+	/* TODO: check if correct/documented to do this for non-monitor completions */
+	if (ch->efId > 0)
+		seq_efSet(sp->ss, ch->efId);
+
+	/* Wake up each state set that uses this channel in an event */
+	seqWakeup(sp, ch->eventNum);
 }
 
 struct putq_cp_arg {
-- 
GitLab