From 3220b2ddc5968f494088a3a83ba0b69f449abab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tibor=20K=C3=A1lm=C3=A1n?= Date: Fri, 3 Nov 2023 10:41:44 +0100 Subject: [PATCH 1/2] getAttrInfo race test --- ibmmq/ibmmq_test.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/ibmmq/ibmmq_test.go b/ibmmq/ibmmq_test.go index 7e5f68e..16722e9 100644 --- a/ibmmq/ibmmq_test.go +++ b/ibmmq/ibmmq_test.go @@ -319,3 +319,22 @@ func TestNewMQDLHWithMQMD(t *testing.T) { t.Fail() } } + +func TestGetAttrInfoConcurrentCalls(t *testing.T) { + // NOTE: This test should be run with `go test -race`. + attrs := []int32{ + MQCA_BACKOUT_REQ_Q_NAME, + MQIA_BACKOUT_THRESHOLD, + } + count := 1_000 + doneCh := make(chan struct{}, count) + for i := 0; i < count; i++ { + go func() { + getAttrInfo(attrs) + doneCh <- struct{}{} + }() + } + for i := 0; i < count; i++ { + <-doneCh + } +} From 2fdc74158e2a68f86cbf1f0a06749747df1aa529 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tibor=20K=C3=A1lm=C3=A1n?= Date: Fri, 3 Nov 2023 10:42:25 +0100 Subject: [PATCH 2/2] Use sync.Once to ensure mqInqLength is initialized once --- ibmmq/mqiattrs.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ibmmq/mqiattrs.go b/ibmmq/mqiattrs.go index 90007c7..0e57470 100644 --- a/ibmmq/mqiattrs.go +++ b/ibmmq/mqiattrs.go @@ -61,6 +61,7 @@ import "C" import ( "fmt" "os" + "sync" ) /* @@ -130,7 +131,7 @@ var mqInqLength = map[int32]int32{ C.MQCA_XMIT_Q_NAME: C.MQ_Q_NAME_LENGTH, } -var charAttrsAdded = false +var charAttrsAddedOnce sync.Once /* * Return how many char & int attributes are in the list of selectors, and the @@ -141,7 +142,7 @@ func getAttrInfo(attrs []int32) (int, int, int) { var charAttrCount = 0 var intAttrCount = 0 - if !charAttrsAdded { + charAttrsAddedOnce.Do(func() { maxNewAttrs := C.MAX_NEW_MQCA_ATTRS attrVals := make([]C.MQLONG, maxNewAttrs) attrLens := make([]C.MQLONG, maxNewAttrs) @@ -155,8 +156,7 @@ func getAttrInfo(attrs []int32) (int, int, int) { for i := 0; i < addedAttrs; i++ { mqInqLength[int32(attrVals[i])] = int32(attrLens[i]) } - charAttrsAdded = true - } + }) for i := 0; i < len(attrs); i++ { if v, ok := mqInqLength[attrs[i]]; ok {