Commit 2bfd4d5f authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 6d0aae55
......@@ -749,56 +749,64 @@ func (t *T) fatalfInNonMain(format string, argv ...interface{}) {
runtime.Goexit()
}
// T overrides FailNow/Fatal/Fatalf to also nak all in-progress sends.
// T overrides FailNow/Fatal/Fatalf to also cancel all in-progress sends.
func (t *T) FailNow() {
t.Helper()
// mark streamTab no longer operational XXX ok?
// mark streamTab no longer operational
t.streamTabMu.Lock()
streamTab := t.streamTab
t.streamTab = nil
t.streamTabMu.Unlock()
type sendInfo struct{ch Chan; msg *Msg}
var sendv []sendInfo
for _, ch := range streamTab {
var sendv []sendInfo // sends are pending here
var quietv []Chan // this channels are quiet
// order channels by name
var streams []string
for __ := range streamTab {
streams = append(streams, __)
}
sort.Slice(streams, func(i, j int) bool {
return strings.Compare(streams[i], streams[j]) < 0
})
for _, stream := range streams {
ch := streamTab[stream]
// check whether someone is sending on channels without blocking.
// if yes - report to sender there is a problem - so it can cancel its task.
select {
case msg := <-ch._rxq():
sendv = append(sendv, sendInfo{ch, msg})
default:
quietv = append(quietv, ch)
}
}
// order channels by name
sort.Slice(sendv, func(i, j int) bool {
return strings.Compare(sendv[i].ch.name(), sendv[j].ch.name()) < 0
})
bad := ""
if len(sendv) == 0 {
bad += fmt.Sprintf("noone is sending\n")
bad += fmt.Sprintf("no pending events\n")
} else {
bad += fmt.Sprintf("there are %d pending sender(s) on other channel(s):\n", len(sendv))
//bad += fmt.Sprintf("the following send(s) are pending:\n"
bad += fmt.Sprintf("%d pending event(s):\n", len(sendv))
for _, __ := range sendv {
bad += fmt.Sprintf("%s\t<- %T %v\n", __.ch.name(), __.msg.Event, __.msg.Event)
}
}
for _, ch := range quietv {
bad += fmt.Sprintf("# %s\n", ch.name())
}
// log the deadlock details and nak senders that we received from.
// nak them only after deadlock printout, so that the deadlock text
// comes first, and their "panics" don't get intermixed with it.
// log the details and nak senders that we received from.
// nak them only after details printout, so that our text comes first,
// and their "panics" don't get intermixed with it.
t.Log(bad)
for _, __ := range t.nakq {
__.msg.nak(__.why)
}
for _, __ := range sendv {
__.msg.nak("canceled (test failed)") // XXX reason can be custom / different
__.msg.nak("canceled (test failed)")
}
// in any case close channel where future Sends may arrive so that will "panic" too.
// in any case close channel where future Sends may arrive so that they will "panic" too.
for _, ch := range streamTab {
ch.Close()
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment