Skip to content
This repository was archived by the owner on Mar 27, 2024. It is now read-only.

Commit 9d720eb

Browse files
authored
Merge pull request #278 from apourchet/pourchet/fix-race-condition
Fixed concurrent map write in image diffing
2 parents 4e6ac73 + 2fea921 commit 9d720eb

File tree

1 file changed

+18
-13
lines changed

1 file changed

+18
-13
lines changed

cmd/diff.go

+18-13
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,12 @@ func checkFilenameFlag(_ []string) error {
7171
}
7272

7373
// processImage is a concurrency-friendly wrapper around getImageForName
74-
func processImage(imageName string, imageMap map[string]*pkgutil.Image, wg *sync.WaitGroup, errChan chan<- error) {
75-
defer wg.Done()
74+
func processImage(imageName string, errChan chan<- error) *pkgutil.Image {
7675
image, err := getImage(imageName)
7776
if err != nil {
7877
errChan <- fmt.Errorf("error retrieving image %s: %s", imageName, err)
7978
}
80-
imageMap[imageName] = &image
79+
return &image
8180
}
8281

8382
// collects errors from a channel and combines them
@@ -109,18 +108,24 @@ func diffImages(image1Arg, image2Arg string, diffArgs []string) error {
109108

110109
logrus.Infof("starting diff on images %s and %s, using differs: %s\n", image1Arg, image2Arg, diffArgs)
111110

112-
imageMap := map[string]*pkgutil.Image{}
111+
var image1, image2 *pkgutil.Image
113112
errChan := make(chan error, 2)
114113

115-
go processImage(image1Arg, imageMap, &wg, errChan)
116-
go processImage(image2Arg, imageMap, &wg, errChan)
114+
go func() {
115+
defer wg.Done()
116+
image1 = processImage(image1Arg, errChan)
117+
}()
118+
go func() {
119+
defer wg.Done()
120+
image2 = processImage(image2Arg, errChan)
121+
}()
117122

118123
wg.Wait()
119124
close(errChan)
120125

121126
if noCache && !save {
122-
defer pkgutil.CleanupImage(*imageMap[image1Arg])
123-
defer pkgutil.CleanupImage(*imageMap[image2Arg])
127+
defer pkgutil.CleanupImage(*image1)
128+
defer pkgutil.CleanupImage(*image2)
124129
}
125130

126131
if err := readErrorsFromChannel(errChan); err != nil {
@@ -129,8 +134,8 @@ func diffImages(image1Arg, image2Arg string, diffArgs []string) error {
129134

130135
logrus.Info("computing diffs")
131136
req := differs.DiffRequest{
132-
Image1: *imageMap[image1Arg],
133-
Image2: *imageMap[image2Arg],
137+
Image1: *image1,
138+
Image2: *image2,
134139
DiffTypes: diffTypes}
135140
diffs, err := req.GetDiff()
136141
if err != nil {
@@ -140,15 +145,15 @@ func diffImages(image1Arg, image2Arg string, diffArgs []string) error {
140145

141146
if filename != "" {
142147
logrus.Info("computing filename diffs")
143-
err := diffFile(imageMap[image1Arg], imageMap[image2Arg])
148+
err := diffFile(image1, image2)
144149
if err != nil {
145150
return err
146151
}
147152
}
148153

149154
if noCache && save {
150-
logrus.Infof("images were saved at %s and %s", imageMap[image1Arg].FSPath,
151-
imageMap[image2Arg].FSPath)
155+
logrus.Infof("images were saved at %s and %s", image1.FSPath,
156+
image2.FSPath)
152157
}
153158
return nil
154159
}

0 commit comments

Comments
 (0)