diff options
| -rw-r--r-- | env.go | 10 | ||||
| -rw-r--r-- | gui_test.go | 12 | ||||
| -rw-r--r-- | kill.go | 42 | ||||
| -rw-r--r-- | kill_test.go | 76 | ||||
| -rw-r--r-- | mux.go | 12 |
5 files changed, 81 insertions, 71 deletions
@@ -34,7 +34,7 @@ type Env interface { type env struct { events <-chan Event draw chan<- func(draw.Image) image.Rectangle - attachChan chan<- attachable + attachChan chan<- victim kill chan<- bool dead <-chan bool detachChan <-chan bool @@ -57,7 +57,7 @@ func newEnv(parent Env, ) Env { events := share.NewQueue[Event]() drawChan := make(chan func(draw.Image) image.Rectangle) - child := newAttachHandler() + child := newKiller() kill := make(chan bool) dead := make(chan bool) detachFromParent := make(chan bool) @@ -77,8 +77,8 @@ func newEnv(parent Env, defer close(kill) defer func() { go drain(drawChan) - child.kill <- true - <-child.dead + child.Kill() <- true + <-child.Dead() }() for { @@ -121,7 +121,7 @@ func (e env) Dead() <-chan bool { return e.dead } -func (e env) attach() chan<- attachable { +func (e env) attach() chan<- victim { return e.attachChan } diff --git a/gui_test.go b/gui_test.go index c8e685e..3878f90 100644 --- a/gui_test.go +++ b/gui_test.go @@ -41,7 +41,7 @@ type dummyEnv struct { kill chan<- bool dead <-chan bool - attachChan chan<- attachable + attachChan chan<- victim } func newDummyEnv(size image.Rectangle) dummyEnv { @@ -51,7 +51,7 @@ func newDummyEnv(size image.Rectangle) dummyEnv { kill := make(chan bool) dead := make(chan bool) - attached := newAttachHandler() + child := newKiller() go func() { defer func() { @@ -64,8 +64,8 @@ func newDummyEnv(size image.Rectangle) dummyEnv { defer close(events.Enqueue) defer func() { go drain(drawIn) - attached.kill <- true - <-attached.dead + child.Kill() <- true + <-child.Dead() }() for { @@ -80,7 +80,7 @@ func newDummyEnv(size image.Rectangle) dummyEnv { events.Enqueue <- Resize{size} - return dummyEnv{events, drawIn, drawOut, kill, dead, attached.attach()} + return dummyEnv{events, drawIn, drawOut, kill, dead, child.attach()} } func (de dummyEnv) Events() <-chan Event { @@ -99,7 +99,7 @@ func (de dummyEnv) Dead() <-chan bool { return de.dead } -func (de dummyEnv) attach() chan<- attachable { +func (de dummyEnv) attach() chan<- victim { return de.attachChan } @@ -7,34 +7,36 @@ type Killable interface { Dead() <-chan bool } -// A killer can kill the `victim' that is attached to it. +// A killer can kill the victim that is attached to it. // The victim can attach itself to the killer by sending itself via the killer's attach() channel. // The victim can detach itself by sending a signal via its own detach() channel. // // Only one victim can be attached to the killer at a time. // Further messages sent on the attach() channel will block until the current victim is detached. +// +// If the killer is killed while a victim is attached, it kills the victim. +// When killed, the victim must detach itself before dying. type killer interface { - attach() chan<- attachable -} + attach() chan<- victim -type attachable interface { Killable - // Sending to detach() will detach the object from the killer it is attached to. +} + +type victim interface { + // Sending to detach() will detach the victim from the killer it is attached to. detach() <-chan bool + + Killable } -// attachHandler implements killer. It allows victims to attach themselves via the attach channel. -// There can only be one attached victim at a time. -// If attachHandler is killed while a victim is attached, it kills the victim. -// When killed, the victim must detach itself before dying. -type attachHandler struct { - attachChan chan<- attachable +type _killer struct { + attachChan chan<- victim kill chan<- bool dead <-chan bool } -func newAttachHandler() attachHandler { - attach := make(chan attachable) +func newKiller() killer { + attach := make(chan victim) kill := make(chan bool) dead := make(chan bool) @@ -63,9 +65,17 @@ func newAttachHandler() attachHandler { } }() - return attachHandler{attach, kill, dead} + return _killer{attach, kill, dead} +} + +func (k _killer) attach() chan<- victim { + return k.attachChan +} + +func (k _killer) Kill() chan<- bool { + return k.kill } -func (ah attachHandler) attach() chan<- attachable { - return ah.attachChan +func (k _killer) Dead() <-chan bool { + return k.dead } diff --git a/kill_test.go b/kill_test.go index d11e54c..f926e44 100644 --- a/kill_test.go +++ b/kill_test.go @@ -5,52 +5,52 @@ import ( "testing" ) -// Kill the attachHandler with no victim attached. -func TestAttachHandlerKill(t *testing.T) { - handler := newAttachHandler() - if !trySend(handler.kill, true, timeout) { - t.Errorf("kill attachHandler timed out after %v", timeout) +// Kill the killer with no victim attached. +func TestKillerKill(t *testing.T) { + killer := newKiller() + if !trySend(killer.Kill(), true, timeout) { + t.Errorf("kill timed out after %v", timeout) } - if _, ok := tryRecv(handler.dead, timeout); !ok { - t.Errorf("no dead signal from attachHandler after %v", timeout) + if _, ok := tryRecv(killer.Dead(), timeout); !ok { + t.Errorf("no dead signal from killer after %v", timeout) } } -// Kill the attachHandler with a victim attached. -func TestAttachHandlerAttachKill(t *testing.T) { - handler := newAttachHandler() - victim, err := newDummyAttachable(handler) +// Kill the killer with a victim attached. +func TestKillerAttachKill(t *testing.T) { + killer := newKiller() + victim, err := newDummyVictim(killer) if err != nil { t.Error(err) } - // Kill attachHandler. - if !trySend(handler.kill, true, timeout) { - t.Errorf("failed to kill attachHandler after %v", timeout) + // Kill the killer. + if !trySend(killer.Kill(), true, timeout) { + t.Errorf("failed to kill killer after %v", timeout) } - if _, ok := tryRecv(handler.dead, timeout); !ok { - t.Errorf("attachHandler not dead after %v", timeout) + if _, ok := tryRecv(killer.Dead(), timeout); !ok { + t.Errorf("killer not dead after %v", timeout) } // victim.Dead() should now be closed. if _, notClosed := <-victim.Dead(); notClosed { - t.Errorf("victim not dead after killing attachHandler") + t.Errorf("victim not dead after killing killer") } } // Detach the victim and attach another in its place. -func TestAttachHandlerReattach(t *testing.T) { - handler := newAttachHandler() +func TestKillerReattach(t *testing.T) { + killer := newKiller() // Attach first victim. - victim1, err := newDummyAttachable(handler) + victim1, err := newDummyVictim(killer) if err != nil { t.Error(err) } // Try to attach second victim while first still attached—should fail. - if _, err := newDummyAttachable(handler); err == nil { - t.Errorf("attachHandler accepted another victim while the first was still attached.") + if _, err := newDummyVictim(killer); err == nil { + t.Errorf("killer accepted another victim while the first was still attached.") } // Detach first victim. @@ -62,23 +62,23 @@ func TestAttachHandlerReattach(t *testing.T) { } // Attach second victim. - if _, err := newDummyAttachable(handler); err != nil { + if _, err := newDummyVictim(killer); err != nil { t.Error(err) } - handler.kill <- true - <-handler.dead + killer.Kill() <- true + <-killer.Dead() } -type dummyAttachable struct { +type dummyVictim struct { kill chan<- bool dead <-chan bool detachChan <-chan bool } -// newDummyAttachable returns a dummyAttachable that is attached to parent, +// newDummyVictim returns a victim that is attached to parent, // or error if the parent does not accept the attach. -func newDummyAttachable(parent killer) (attachable, error) { +func newDummyVictim(parent killer) (victim, error) { kill := make(chan bool) dead := make(chan bool) detachChan := make(chan bool) @@ -92,21 +92,21 @@ func newDummyAttachable(parent killer) (attachable, error) { close(dead) }() - da := dummyAttachable{kill, dead, detachChan} - if !trySend(parent.attach(), attachable(da), timeout) { - return da, fmt.Errorf("failed to attach after %v", timeout) + dummy := dummyVictim{kill, dead, detachChan} + if !trySend(parent.attach(), victim(dummy), timeout) { + return dummy, fmt.Errorf("failed to attach after %v", timeout) } - return da, nil + return dummy, nil } -func (da dummyAttachable) Kill() chan<- bool { - return da.kill +func (dv dummyVictim) Kill() chan<- bool { + return dv.kill } -func (da dummyAttachable) Dead() <-chan bool { - return da.dead +func (dv dummyVictim) Dead() <-chan bool { + return dv.dead } -func (da dummyAttachable) detach() <-chan bool { - return da.detachChan +func (dv dummyVictim) detach() <-chan bool { + return dv.detachChan } @@ -110,7 +110,7 @@ func (mux Mux) detach() <-chan bool { type muxEnv struct { events share.Queue[Event] draw chan<- func(draw.Image) image.Rectangle - attachChan chan<- attachable + attachChan chan<- victim kill chan<- bool dead <-chan bool detachFromMux <-chan bool @@ -119,7 +119,7 @@ type muxEnv struct { func (mux Mux) MakeEnv() Env { events := share.NewQueue[Event]() drawChan := make(chan func(draw.Image) image.Rectangle) - attached := newAttachHandler() + child := newKiller() kill := make(chan bool) dead := make(chan bool) detachFromMux := make(chan bool) @@ -127,7 +127,7 @@ func (mux Mux) MakeEnv() Env { env := muxEnv{ events: events, draw: drawChan, - attachChan: attached.attach(), + attachChan: child.attach(), kill: kill, dead: dead, detachFromMux: detachFromMux, @@ -150,8 +150,8 @@ func (mux Mux) MakeEnv() Env { }() defer func() { - attached.kill <- true - <-attached.dead + child.Kill() <- true + <-child.Dead() }() defer func() { go drain(drawChan) @@ -186,7 +186,7 @@ func (env muxEnv) Dead() <-chan bool { return env.dead } -func (env muxEnv) attach() chan<- attachable { +func (env muxEnv) attach() chan<- victim { return env.attachChan } |