From 2da5a54817dd0a6540e3c2f9895068eb5dffe04f Mon Sep 17 00:00:00 2001 From: Silvan Jegen Date: Fri, 23 Oct 2015 19:24:56 +0200 Subject: Remove race condition By making sure that we finish writing to the out channel before returning we don't hit the case that the out channel is closed when we try to write to it. --- gwic.go | 41 +++++++++++++++-------------------------- 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/gwic.go b/gwic.go index 98ee34f..cb086b2 100644 --- a/gwic.go +++ b/gwic.go @@ -26,25 +26,21 @@ func (q *queue) insert(s string) { type work struct { c chan string left int + done chan struct{} } -func printWithContext(all []string, ind, ctxlen int) { - var slice []string - slice = append(slice, "\""+all[ind]+"\"") - - if len(all[:ind]) < ctxlen { - slice = append(all[:ind], slice...) - } else { - slice = append(all[ind-ctxlen:ind], slice...) - } +func (w *work) finish() { + close(w.c) + w.done <- struct{}{} + return +} - if len(all[ind:]) < ctxlen { - slice = append(slice, all[ind+1:]...) - } else { - slice = append(slice, all[ind+1:ind+ctxlen]...) +func (w *work) print_kwic(sl []string, out chan string) { + for word := range w.c { + sl = append(sl, word) } - - fmt.Fprintf(tw, "%s\n", strings.Join(slice, "\t")) + out <- strings.Join(sl, "\t") + <-w.done } func feedworkers(wlist []*work, w string) []*work { @@ -59,7 +55,7 @@ func feedworkers(wlist []*work, w string) []*work { for _, wc := range wlist { if wc.left == 0 { - close(wc.c) + wc.finish() //fmt.Fprintf(os.Stderr, "Closed wc: %s\n", wc) // TODO: remove the right one? if len(wlist) >= 1 { @@ -75,13 +71,6 @@ func feedworkers(wlist []*work, w string) []*work { return ret } -func print_kwic(sl []string, c chan string, out chan string) { - for w := range c { - sl = append(sl, w) - } - out <- strings.Join(sl, "\t") -} - func printqueue(q *queue, words chan string, left int, out chan string) { var hungryhippos []*work @@ -98,7 +87,7 @@ func printqueue(q *queue, words chan string, left int, out chan string) { //fmt.Fprintf(os.Stdout, "%q totally matched %q\n", w, kw) //fmt.Fprintf(os.Stdout, "queue was %v\n", q.q) - wc := &work{c: make(chan string), left: 5} + wc := &work{c: make(chan string, 10), left: 5, done: make(chan struct{})} hungryhippos = feedworkers(hungryhippos, w) @@ -108,10 +97,10 @@ func printqueue(q *queue, words chan string, left int, out chan string) { //fmt.Fprintf(os.Stdout, "copied %d : %v\n", n, sl) hungryhippos = append(hungryhippos, wc) //fmt.Fprintf(os.Stderr, "appended hungryhippos: %v %d\n", hungryhippos, len(hungryhippos)) - go print_kwic(sl, wc.c, out) + go wc.print_kwic(sl, out) } for _, wc := range hungryhippos { - close(wc.c) + wc.finish() } close(out) } -- cgit v1.2.3