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

.

parent 6d0aae55
...@@ -749,56 +749,64 @@ func (t *T) fatalfInNonMain(format string, argv ...interface{}) { ...@@ -749,56 +749,64 @@ func (t *T) fatalfInNonMain(format string, argv ...interface{}) {
runtime.Goexit() 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() { func (t *T) FailNow() {
t.Helper() t.Helper()
// mark streamTab no longer operational XXX ok? // mark streamTab no longer operational
t.streamTabMu.Lock() t.streamTabMu.Lock()
streamTab := t.streamTab streamTab := t.streamTab
t.streamTab = nil t.streamTab = nil
t.streamTabMu.Unlock() t.streamTabMu.Unlock()
type sendInfo struct{ch Chan; msg *Msg} type sendInfo struct{ch Chan; msg *Msg}
var sendv []sendInfo var sendv []sendInfo // sends are pending here
for _, ch := range streamTab { 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. // 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 { select {
case msg := <-ch._rxq(): case msg := <-ch._rxq():
sendv = append(sendv, sendInfo{ch, msg}) sendv = append(sendv, sendInfo{ch, msg})
default: 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 := "" bad := ""
if len(sendv) == 0 { if len(sendv) == 0 {
bad += fmt.Sprintf("noone is sending\n") bad += fmt.Sprintf("no pending events\n")
} else { } else {
bad += fmt.Sprintf("there are %d pending sender(s) on other channel(s):\n", len(sendv)) bad += fmt.Sprintf("%d pending event(s):\n", len(sendv))
//bad += fmt.Sprintf("the following send(s) are pending:\n"
for _, __ := range sendv { for _, __ := range sendv {
bad += fmt.Sprintf("%s\t<- %T %v\n", __.ch.name(), __.msg.Event, __.msg.Event) 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. // log the details and nak senders that we received from.
// nak them only after deadlock printout, so that the deadlock text // nak them only after details printout, so that our text comes first,
// comes first, and their "panics" don't get intermixed with it. // and their "panics" don't get intermixed with it.
t.Log(bad) t.Log(bad)
for _, __ := range t.nakq { for _, __ := range t.nakq {
__.msg.nak(__.why) __.msg.nak(__.why)
} }
for _, __ := range sendv { 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 { for _, ch := range streamTab {
ch.Close() 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