Skip to content

Commit

Permalink
Merge pull request #25 from benmoss/fix-confirms-deadlock
Browse files Browse the repository at this point in the history
Fix deadlock between publishing and receiving confirms
  • Loading branch information
MirahImage authored Nov 17, 2021
2 parents 968d3e4 + 08f1cc5 commit 52a5b5a
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 7 deletions.
18 changes: 11 additions & 7 deletions confirms.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ import "sync"

// confirms resequences and notifies one or multiple publisher confirmation listeners
type confirms struct {
m sync.Mutex
listeners []chan Confirmation
sequencer map[uint64]Confirmation
published uint64
expecting uint64
m sync.Mutex
listeners []chan Confirmation
sequencer map[uint64]Confirmation
published uint64
publishedMut sync.Mutex
expecting uint64
}

// newConfirms allocates a confirms
Expand All @@ -34,8 +35,8 @@ func (c *confirms) Listen(l chan Confirmation) {

// Publish increments the publishing counter
func (c *confirms) Publish() uint64 {
c.m.Lock()
defer c.m.Unlock()
c.publishedMut.Lock()
defer c.publishedMut.Unlock()

c.published++
return c.published
Expand All @@ -53,6 +54,9 @@ func (c *confirms) confirm(confirmation Confirmation) {

// resequence confirms any out of order delivered confirmations
func (c *confirms) resequence() {
c.publishedMut.Lock()
defer c.publishedMut.Unlock()

for c.expecting <= c.published {
sequenced, found := c.sequencer[c.expecting]
if !found {
Expand Down
20 changes: 20 additions & 0 deletions confirms_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,26 @@ func TestConfirmOneResequences(t *testing.T) {
}
}

func TestConfirmAndPublishDoNotDeadlock(t *testing.T) {
var (
c = newConfirms()
l = make(chan Confirmation)
iterations = 10
)
c.Listen(l)

go func() {
for i := 0; i < iterations; i++ {
c.One(Confirmation{uint64(i + 1), true})
}
}()

for i := 0; i < iterations; i++ {
c.Publish()
<-l
}
}

func TestConfirmMixedResequences(t *testing.T) {
var (
fixtures = []Confirmation{
Expand Down

0 comments on commit 52a5b5a

Please sign in to comment.