Added mutexes to writes
All checks were successful
/ test (push) Successful in 1m5s

This commit is contained in:
Leon Mika 2025-05-12 20:03:27 +10:00
parent 6dc923b6ae
commit 56485330dd

17
bus.go
View file

@ -1,5 +1,7 @@
package events package events
import "sync"
type Bus struct { type Bus struct {
topics map[string]*topic topics map[string]*topic
} }
@ -12,7 +14,7 @@ func (d *Bus) On(event string, receiver interface{}) *Subscription {
// TODO: make thread safe // TODO: make thread safe
t, hasTopic := d.topics[event] t, hasTopic := d.topics[event]
if !hasTopic { if !hasTopic {
t = &topic{} t = &topic{mutex: sync.Mutex{}, head: nil, tail: nil}
d.topics[event] = t d.topics[event] = t
} }
@ -38,12 +40,17 @@ func (d *Bus) TryFire(event string, args ...interface{}) error {
preparedArgs := prepareArgs(args) preparedArgs := prepareArgs(args)
topic.mutex.Lock()
var head = topic.head
topic.mutex.Unlock()
var errs []error var errs []error
var lastSub *Subscription = nil var lastSub *Subscription = nil
for sub := topic.head; sub != nil; sub = sub.next { for sub := head; sub != nil; sub = sub.next {
// Remove unsubscribers // Remove unsubscribers
if sub.remove { if sub.remove {
topic.mutex.Lock()
if lastSub == nil { if lastSub == nil {
topic.head = sub.next topic.head = sub.next
} else { } else {
@ -52,6 +59,7 @@ func (d *Bus) TryFire(event string, args ...interface{}) error {
if topic.tail == sub { if topic.tail == sub {
topic.tail = lastSub topic.tail = lastSub
} }
topic.mutex.Unlock()
continue continue
} }
lastSub = sub lastSub = sub
@ -72,11 +80,16 @@ func (d *Bus) TryFire(event string, args ...interface{}) error {
} }
type topic struct { type topic struct {
// mutex protects writes to the head and tail
mutex sync.Mutex
head *Subscription head *Subscription
tail *Subscription tail *Subscription
} }
func (t *topic) addSubscriber(sub *Subscription) { func (t *topic) addSubscriber(sub *Subscription) {
t.mutex.Lock()
defer t.mutex.Unlock()
if t.head == nil { if t.head == nil {
t.head = sub t.head = sub
} }