diff options
author | Silvan Jegen <s.jegen@gmail.com> | 2015-10-23 19:24:56 +0200 |
---|---|---|
committer | Silvan Jegen <s.jegen@gmail.com> | 2015-10-27 21:40:57 +0100 |
commit | 2da5a54817dd0a6540e3c2f9895068eb5dffe04f (patch) | |
tree | bb1a18a736772f852043192d9183a2a9de674b03 | |
parent | a29104ce4bbe4afc2aa1cca3b941747237a70c49 (diff) |
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.
-rw-r--r-- | gwic.go | 41 |
1 files changed, 15 insertions, 26 deletions
@@ -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) } |