Browse code

Fix a race in maintaining the journald reader list

The journald log reader keeps a map of following readers so that it can
close them properly when the journald reader object itself is closed,
but it was possible for its worker goroutine to be scheduled so that the
worker attempted to remove a reader from the map before the reader had
been added to the map. This patch adds the item to the map before
starting the goroutine which is expected to eventually remove it.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com> (github: nalind)

Nalin Dahyabhai authored on 2016/03/18 05:17:11
Showing 1 changed files
... ...
@@ -173,6 +173,9 @@ drain:
173 173
 }
174 174
 
175 175
 func (s *journald) followJournal(logWatcher *logger.LogWatcher, config logger.ReadConfig, j *C.sd_journal, pfd [2]C.int, cursor string) {
176
+	s.readers.mu.Lock()
177
+	s.readers.readers[logWatcher] = logWatcher
178
+	s.readers.mu.Unlock()
176 179
 	go func() {
177 180
 		// Keep copying journal data out until we're notified to stop.
178 181
 		for C.wait_for_data_or_close(j, pfd[0]) == 1 {
... ...
@@ -184,9 +187,6 @@ func (s *journald) followJournal(logWatcher *logger.LogWatcher, config logger.Re
184 184
 		delete(s.readers.readers, logWatcher)
185 185
 		s.readers.mu.Unlock()
186 186
 	}()
187
-	s.readers.mu.Lock()
188
-	s.readers.readers[logWatcher] = logWatcher
189
-	s.readers.mu.Unlock()
190 187
 	// Wait until we're told to stop.
191 188
 	select {
192 189
 	case <-logWatcher.WatchClose():