Fixed a race condition in builder/vmware/common/driver_parser.go due to a misunderstanding how channels work when you close them.
This commit is contained in:
parent
737e951685
commit
594ed950c7
|
@ -17,8 +17,9 @@ type sentinelSignaller chan struct{}
|
|||
|
||||
/** low-level parsing */
|
||||
// strip the comments and extraneous newlines from a byte channel
|
||||
func uncomment(eof sentinelSignaller, in <-chan byte) chan byte {
|
||||
func uncomment(eof sentinelSignaller, in <-chan byte) (chan byte, sentinelSignaller) {
|
||||
out := make(chan byte)
|
||||
eoc := make(sentinelSignaller)
|
||||
|
||||
go func(in <-chan byte, out chan byte) {
|
||||
var endofline bool
|
||||
|
@ -40,16 +41,19 @@ func uncomment(eof sentinelSignaller, in <-chan byte) chan byte {
|
|||
}
|
||||
}
|
||||
}
|
||||
close(eoc)
|
||||
}(in, out)
|
||||
return out
|
||||
return out, eoc
|
||||
}
|
||||
|
||||
// convert a byte channel into a channel of pseudo-tokens
|
||||
func tokenizeDhcpConfig(eof sentinelSignaller, in chan byte) chan string {
|
||||
func tokenizeDhcpConfig(eof sentinelSignaller, in chan byte) (chan string, sentinelSignaller) {
|
||||
var ch byte
|
||||
var state string
|
||||
var quote bool
|
||||
|
||||
eot := make(sentinelSignaller)
|
||||
|
||||
out := make(chan string)
|
||||
go func(out chan string) {
|
||||
for stillReading := true; stillReading; {
|
||||
|
@ -106,8 +110,9 @@ func tokenizeDhcpConfig(eof sentinelSignaller, in chan byte) chan string {
|
|||
if len(state) > 0 {
|
||||
out <- state
|
||||
}
|
||||
close(eot)
|
||||
}(out)
|
||||
return out
|
||||
return out, eot
|
||||
}
|
||||
|
||||
/** mid-level parsing */
|
||||
|
@ -220,12 +225,14 @@ func parseDhcpConfig(eof sentinelSignaller, in chan string) (tkGroup, error) {
|
|||
return result, nil
|
||||
}
|
||||
|
||||
func tokenizeNetworkMapConfig(eof sentinelSignaller, in chan byte) chan string {
|
||||
func tokenizeNetworkMapConfig(eof sentinelSignaller, in chan byte) (chan string, sentinelSignaller) {
|
||||
var ch byte
|
||||
var state string
|
||||
var quote bool
|
||||
var lastnewline bool
|
||||
|
||||
eot := make(sentinelSignaller)
|
||||
|
||||
out := make(chan string)
|
||||
go func(out chan string) {
|
||||
for stillReading := true; stillReading; {
|
||||
|
@ -291,8 +298,9 @@ func tokenizeNetworkMapConfig(eof sentinelSignaller, in chan byte) chan string {
|
|||
if len(state) > 0 {
|
||||
out <- state
|
||||
}
|
||||
close(eot)
|
||||
}(out)
|
||||
return out
|
||||
return out, eot
|
||||
}
|
||||
|
||||
func parseNetworkMapConfig(eof sentinelSignaller, in chan string) (NetworkMap, error) {
|
||||
|
@ -966,9 +974,9 @@ type DhcpConfiguration []configDeclaration
|
|||
|
||||
func ReadDhcpConfiguration(fd *os.File) (DhcpConfiguration, error) {
|
||||
fromfile, eof := consumeFile(fd)
|
||||
uncommented := uncomment(eof, fromfile)
|
||||
tokenized := tokenizeDhcpConfig(eof, uncommented)
|
||||
parsetree, err := parseDhcpConfig(eof, tokenized)
|
||||
uncommented, eoc := uncomment(eof, fromfile)
|
||||
tokenized, eot := tokenizeDhcpConfig(eoc, uncommented)
|
||||
parsetree, err := parseDhcpConfig(eot, tokenized)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1064,10 +1072,10 @@ type NetworkNameMapper interface {
|
|||
func ReadNetworkMap(fd *os.File) (NetworkMap, error) {
|
||||
|
||||
fromfile, eof := consumeFile(fd)
|
||||
uncommented := uncomment(eof, fromfile)
|
||||
tokenized := tokenizeNetworkMapConfig(eof, uncommented)
|
||||
uncommented, eoc := uncomment(eof, fromfile)
|
||||
tokenized, eot := tokenizeNetworkMapConfig(eoc, uncommented)
|
||||
|
||||
result, err := parseNetworkMapConfig(eof, tokenized)
|
||||
result, err := parseNetworkMapConfig(eot, tokenized)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1100,11 +1108,13 @@ func (e *NetworkMap) repr() string {
|
|||
}
|
||||
|
||||
/*** parser for VMware Fusion's networking file */
|
||||
func tokenizeNetworkingConfig(eof sentinelSignaller, in chan byte) chan string {
|
||||
func tokenizeNetworkingConfig(eof sentinelSignaller, in chan byte) (chan string, sentinelSignaller) {
|
||||
var ch byte
|
||||
var state string
|
||||
var repeat_newline bool
|
||||
|
||||
eot := make(sentinelSignaller)
|
||||
|
||||
out := make(chan string)
|
||||
go func(out chan string) {
|
||||
for reading := true; reading; {
|
||||
|
@ -1144,13 +1154,16 @@ func tokenizeNetworkingConfig(eof sentinelSignaller, in chan byte) chan string {
|
|||
if len(state) > 0 {
|
||||
out <- state
|
||||
}
|
||||
close(eot)
|
||||
}(out)
|
||||
return out
|
||||
return out, eot
|
||||
}
|
||||
|
||||
func splitNetworkingConfig(eof sentinelSignaller, in chan string) chan []string {
|
||||
func splitNetworkingConfig(eof sentinelSignaller, in chan string) (chan []string, sentinelSignaller) {
|
||||
var out chan []string
|
||||
|
||||
eos := make(sentinelSignaller)
|
||||
|
||||
out = make(chan []string)
|
||||
go func(out chan []string) {
|
||||
row := make([]string, 0)
|
||||
|
@ -1174,8 +1187,9 @@ func splitNetworkingConfig(eof sentinelSignaller, in chan string) chan []string
|
|||
if len(row) > 0 {
|
||||
out <- row
|
||||
}
|
||||
close(eos)
|
||||
}(out)
|
||||
return out
|
||||
return out, eos
|
||||
}
|
||||
|
||||
/// All token types in networking file.
|
||||
|
@ -1642,9 +1656,11 @@ func NetworkingParserByCommand(command string) *func([]string) (*networkingComma
|
|||
return nil
|
||||
}
|
||||
|
||||
func parseNetworkingConfig(eof sentinelSignaller, rows chan []string) chan networkingCommandEntry {
|
||||
func parseNetworkingConfig(eof sentinelSignaller, rows chan []string) (chan networkingCommandEntry, sentinelSignaller) {
|
||||
var out chan networkingCommandEntry
|
||||
|
||||
eop := make(sentinelSignaller)
|
||||
|
||||
out = make(chan networkingCommandEntry)
|
||||
go func(in chan []string, out chan networkingCommandEntry) {
|
||||
for reading := true; reading; {
|
||||
|
@ -1668,8 +1684,9 @@ func parseNetworkingConfig(eof sentinelSignaller, rows chan []string) chan netwo
|
|||
}
|
||||
}
|
||||
}
|
||||
close(eop)
|
||||
}(rows, out)
|
||||
return out
|
||||
return out, eop
|
||||
}
|
||||
|
||||
type NetworkingConfig struct {
|
||||
|
@ -1795,9 +1812,9 @@ func flattenNetworkingConfig(eof sentinelSignaller, in chan networkingCommandEnt
|
|||
func ReadNetworkingConfig(fd *os.File) (NetworkingConfig, error) {
|
||||
// start piecing together different parts of the file
|
||||
fromfile, eof := consumeFile(fd)
|
||||
tokenized := tokenizeNetworkingConfig(eof, fromfile)
|
||||
rows := splitNetworkingConfig(eof, tokenized)
|
||||
entries := parseNetworkingConfig(eof, rows)
|
||||
tokenized, eot := tokenizeNetworkingConfig(eof, fromfile)
|
||||
rows, eos := splitNetworkingConfig(eot, tokenized)
|
||||
entries, eop := parseNetworkingConfig(eos, rows)
|
||||
|
||||
// parse the version
|
||||
parsed_version, err := networkingReadVersion(<-rows)
|
||||
|
@ -1812,7 +1829,7 @@ func ReadNetworkingConfig(fd *os.File) (NetworkingConfig, error) {
|
|||
}
|
||||
|
||||
// convert to a configuration
|
||||
result := flattenNetworkingConfig(eof, entries)
|
||||
result := flattenNetworkingConfig(eop, entries)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue