Fix a race in pkg/discovery/memory

Fix #22964

Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
This commit is contained in:
Akihiro Suda 2016-05-25 02:52:35 +00:00
parent c6179c0b10
commit 6b20c0a9d7

View file

@ -1,16 +1,18 @@
package memory package memory
import ( import (
"sync"
"time" "time"
"github.com/docker/docker/pkg/discovery" "github.com/docker/docker/pkg/discovery"
) )
// Discovery implements a descovery backend that keeps // Discovery implements a discovery backend that keeps
// data in memory. // data in memory.
type Discovery struct { type Discovery struct {
heartbeat time.Duration heartbeat time.Duration
values []string values []string
mu sync.Mutex
} }
func init() { func init() {
@ -41,21 +43,27 @@ func (s *Discovery) Watch(stopCh <-chan struct{}) (<-chan discovery.Entries, <-c
// Send the initial entries if available. // Send the initial entries if available.
var currentEntries discovery.Entries var currentEntries discovery.Entries
var err error
s.mu.Lock()
if len(s.values) > 0 { if len(s.values) > 0 {
var err error
currentEntries, err = discovery.CreateEntries(s.values) currentEntries, err = discovery.CreateEntries(s.values)
if err != nil { }
errCh <- err s.mu.Unlock()
} else {
ch <- currentEntries if err != nil {
} errCh <- err
} else if currentEntries != nil {
ch <- currentEntries
} }
// Periodically send updates. // Periodically send updates.
for { for {
select { select {
case <-ticker.C: case <-ticker.C:
s.mu.Lock()
newEntries, err := discovery.CreateEntries(s.values) newEntries, err := discovery.CreateEntries(s.values)
s.mu.Unlock()
if err != nil { if err != nil {
errCh <- err errCh <- err
continue continue
@ -78,6 +86,8 @@ func (s *Discovery) Watch(stopCh <-chan struct{}) (<-chan discovery.Entries, <-c
// Register adds a new address to the discovery. // Register adds a new address to the discovery.
func (s *Discovery) Register(addr string) error { func (s *Discovery) Register(addr string) error {
s.mu.Lock()
s.values = append(s.values, addr) s.values = append(s.values, addr)
s.mu.Unlock()
return nil return nil
} }