aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/kobject
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2026-05-27 17:58:01 +0900
committerOphestra <cat@gensokyo.uk>2026-05-27 17:58:01 +0900
commitb18f40d974ffc33f3703d46bfe42d6fa2f844a01 (patch)
tree1b713d0d797ab99da540d772255009775fe3c1c3 /internal/kobject
parent12a606105124d1ef3133594afb9e6e0bc2e0ad33 (diff)
internal/kobject: pass action kind for range
Useful for handling most uevents. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/kobject')
-rw-r--r--internal/kobject/kobject.go33
-rw-r--r--internal/kobject/kobject_test.go12
2 files changed, 27 insertions, 18 deletions
diff --git a/internal/kobject/kobject.go b/internal/kobject/kobject.go
index 26359114..2acf3de0 100644
--- a/internal/kobject/kobject.go
+++ b/internal/kobject/kobject.go
@@ -101,7 +101,7 @@ func (o *Object) update(env map[string]string, strip bool) {
// A pendingIterator is a callback currently iterating through objects targeted
// by ongoing events.
type pendingIterator struct {
- f func(o *Object) bool
+ f func(o *Object, act uevent.KobjectAction) bool
done chan<- struct{}
}
@@ -150,12 +150,12 @@ func (s *State) deleteIter(p *pendingIterator) {
}
// dispatchIter broadcasts an [Object] to all alive iterators.
-func (s *State) dispatchIter(o *Object) {
+func (s *State) dispatchIter(o *Object, act uevent.KobjectAction) {
s.iterMu.Lock()
defer s.iterMu.Unlock()
for _, p := range s.iter {
- if !p.f(o) {
+ if !p.f(o, act) {
s.deleteIter(p)
close(p.done)
}
@@ -165,14 +165,17 @@ func (s *State) dispatchIter(o *Object) {
// Range calls f on all current and upcoming [Object] values tracked by s until
// f returns false or the context is cancelled. f must not retain o or modify
// the value it points to.
-func (s *State) Range(ctx context.Context, f func(o *Object) bool) {
+func (s *State) Range(
+ ctx context.Context,
+ f func(o *Object, act uevent.KobjectAction) bool,
+) {
done := make(chan struct{})
p := pendingIterator{f, done}
s.iterMu.Lock()
s.ueventMu.RLock()
for _, o := range s.uevent {
- if !f(o) {
+ if !f(o, uevent.KOBJ_ADD) {
s.ueventMu.RUnlock()
s.iterMu.Unlock()
return
@@ -296,13 +299,13 @@ func (s *State) processEvent(e *Event) {
return
}
- switch e.Action {
+ switch act := e.Action; act {
case uevent.KOBJ_ADD:
if e.Synth == nil {
if o, ok := s.uevent[e.DevPath]; ok {
s.reportErr(e.NewError(EDuplicateAdd, o))
o.merge(e.Env)
- s.dispatchIter(o)
+ s.dispatchIter(o, act)
return
}
}
@@ -312,7 +315,7 @@ func (s *State) processEvent(e *Event) {
}
o.merge(e.Env)
s.uevent[e.DevPath] = o
- s.dispatchIter(o)
+ s.dispatchIter(o, act)
return
case uevent.KOBJ_REMOVE:
@@ -338,14 +341,14 @@ func (s *State) processEvent(e *Event) {
o = e.makeColdboot()
o.merge(e.Env)
s.uevent[e.DevPath] = o
- s.dispatchIter(o)
+ s.dispatchIter(o, act)
return
}
o.update(e.Env, true)
if s.handleChange != nil {
s.handleChange(o, e.Env)
}
- s.dispatchIter(o)
+ s.dispatchIter(o, act)
return
case uevent.KOBJ_MOVE:
@@ -368,7 +371,7 @@ func (s *State) processEvent(e *Event) {
o.merge(e.Env)
s.uevent[e.DevPath] = o
o.DevPath = e.DevPath
- s.dispatchIter(o)
+ s.dispatchIter(o, act)
return
case uevent.KOBJ_ONLINE:
@@ -384,7 +387,7 @@ func (s *State) processEvent(e *Event) {
s.reportErr(e.NewError(EUnexpectedOffline, o))
}
o.Offline = false
- s.dispatchIter(o)
+ s.dispatchIter(o, act)
return
case uevent.KOBJ_OFFLINE:
@@ -400,7 +403,7 @@ func (s *State) processEvent(e *Event) {
s.reportErr(e.NewError(EUnexpectedOffline, o))
}
o.Offline = true
- s.dispatchIter(o)
+ s.dispatchIter(o, act)
return
case uevent.KOBJ_BIND:
@@ -416,7 +419,7 @@ func (s *State) processEvent(e *Event) {
}
o.State = StateBound
o.merge(e.Env)
- s.dispatchIter(o)
+ s.dispatchIter(o, act)
return
case uevent.KOBJ_UNBIND:
@@ -432,7 +435,7 @@ func (s *State) processEvent(e *Event) {
}
o.State = StateNew
o.Driver = ""
- s.dispatchIter(o)
+ s.dispatchIter(o, act)
return
default: // not reached
diff --git a/internal/kobject/kobject_test.go b/internal/kobject/kobject_test.go
index b184e621..c6a54904 100644
--- a/internal/kobject/kobject_test.go
+++ b/internal/kobject/kobject_test.go
@@ -388,7 +388,9 @@ func TestIter(t *testing.T) {
"SEQNUM=1",
}}
synctest.Wait()
- s.Range(t.Context(), func(o *Object) bool { return false })
+ s.Range(t.Context(), func(*Object, uevent.KobjectAction) bool {
+ return false
+ })
var got []*Object
check := func(want []*Object) {
@@ -405,7 +407,7 @@ func TestIter(t *testing.T) {
defer cancel()
var done bool
wg.Go(func() {
- s.Range(ctx, func(o *Object) bool {
+ s.Range(ctx, func(o *Object, _ uevent.KobjectAction) bool {
got = append(got, o.Clone())
return !done
})
@@ -437,7 +439,11 @@ func TestIter(t *testing.T) {
},
})
- wg.Go(func() { s.Range(ctx, func(*Object) bool { return true }) })
+ wg.Go(func() {
+ s.Range(ctx, func(*Object, uevent.KobjectAction) bool {
+ return true
+ })
+ })
synctest.Wait()
iter := reflect.ValueOf(s).Elem().FieldByName("iter")