summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSilvan Jegen <s.jegen@gmail.com>2015-10-23 19:24:56 +0200
committerSilvan Jegen <s.jegen@gmail.com>2015-10-27 21:40:57 +0100
commit2da5a54817dd0a6540e3c2f9895068eb5dffe04f (patch)
treebb1a18a736772f852043192d9183a2a9de674b03
parenta29104ce4bbe4afc2aa1cca3b941747237a70c49 (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.go41
1 files 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)
}