Skip to content

Commit 48c27a6

Browse files
committed
event: fix Resubscribe deadlock when unsubscribing after inner sub ends
Cherry-pick changes from ethereum/go-ethereum#28359
1 parent ed8e9f5 commit 48c27a6

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

event/subscription.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ func ResubscribeErr(backoffMax time.Duration, fn ResubscribeErrFunc) Subscriptio
120120
backoffMax: backoffMax,
121121
fn: fn,
122122
err: make(chan error),
123-
unsub: make(chan struct{}),
123+
unsub: make(chan struct{}, 1),
124124
}
125125
go s.loop()
126126
return s

event/subscription_test.go

+24
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,27 @@ func TestResubscribeWithErrorHandler(t *testing.T) {
154154
t.Fatalf("unexpected subscription errors %v, want %v", subErrs, expectedSubErrs)
155155
}
156156
}
157+
158+
func TestResubscribeWithCompletedSubscription(t *testing.T) {
159+
t.Parallel()
160+
161+
quitProducerAck := make(chan struct{})
162+
quitProducer := make(chan struct{})
163+
164+
sub := ResubscribeErr(100*time.Millisecond, func(ctx context.Context, lastErr error) (Subscription, error) {
165+
return NewSubscription(func(unsubscribed <-chan struct{}) error {
166+
select {
167+
case <-quitProducer:
168+
quitProducerAck <- struct{}{}
169+
return nil
170+
case <-unsubscribed:
171+
return nil
172+
}
173+
}), nil
174+
})
175+
176+
// Ensure producer has started and exited before Unsubscribe
177+
close(quitProducer)
178+
<-quitProducerAck
179+
sub.Unsubscribe()
180+
}

0 commit comments

Comments
 (0)