lang: Don't race with a ^C to the obj.lang calls

If we trigger a close, we must not run the LangClose before we've exited
from the loop, because that loop could race and run code which depends
on LangClose not having run first. So run the loop shutdown, then let
the wait group expire, before shutting down the lang.
This commit is contained in:
James Shubin
2018-03-30 06:36:04 -04:00
parent acdb497b80
commit ef49aa7e08

View File

@@ -178,7 +178,10 @@ func (obj *GAPI) Next() chan gapi.Next {
Err: fmt.Errorf("%s: GAPI is not initialized", Name), Err: fmt.Errorf("%s: GAPI is not initialized", Name),
Exit: true, // exit, b/c programming error? Exit: true, // exit, b/c programming error?
} }
ch <- next select {
case ch <- next:
case <-obj.closeChan:
}
return return
} }
startChan := make(chan struct{}) // start signal startChan := make(chan struct{}) // start signal
@@ -259,9 +262,9 @@ func (obj *GAPI) Close() error {
if !obj.initialized { if !obj.initialized {
return fmt.Errorf("%s: GAPI is not initialized", Name) return fmt.Errorf("%s: GAPI is not initialized", Name)
} }
obj.LangClose() // close lang, esp. if blocked in Stream() wait
close(obj.closeChan) close(obj.closeChan)
obj.wg.Wait() obj.wg.Wait()
obj.LangClose() // close lang, esp. if blocked in Stream() wait
obj.initialized = false // closed = true obj.initialized = false // closed = true
return nil return nil
} }