Skip to content

Potential deadlock due to calling callbacks while holding a lock #35

@sergey-shambir

Description

@sergey-shambir

See golang mutexes aren't recursive / re-entrant

Bus.Publish(...) method locks mutex and calls callbacks under lock, so any access to the bus in callback will cause deadlock.

The following example reproduces issue:

package main

import (
	"fmt"

	"github.com/asaskevich/EventBus"
)

var bus EventBus.Bus

func showbug(a int, b int) {
	fmt.Printf("%d\n", a+b)

	if a == 20 {
		bus.Publish("main:calculator", a+1, b)
	}
}

func main() {
	bus = EventBus.New()
	bus.Subscribe("main:calculator", showbug)
	bus.Publish("main:calculator", 20, 40)
	bus.Unsubscribe("main:calculator", showbug)
}

We use another implementation of eventbus (inspired by yours) where this issue was fixed: github.com/ispringteam/goeventbus (see copySubscriptions method and nextID field)

Feel free to adapt our solution or introduce another one ;)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions