Pull request: data race
Merge in DNS/adguard-home from 2489-data-race to master
Closes #2489.
Squashed commit of the following:
commit 7745b79f0489970f3ba1bb11bb757b998fa6369c
Merge: d070cfd53 93ffed780
Author: Eugene Burkov <e.burkov@adguard.com>
Date: Mon Dec 28 19:00:07 2020 +0300
Merge branch 'master' into 2489-data-race
commit d070cfd53e72b609f305cd8d79d747fbf47dc5f4
Author: Eugene Burkov <e.burkov@adguard.com>
Date: Fri Dec 25 20:31:21 2020 +0300
util: fix ignoring write events bug
commit 725850bdbd96eaf65fb3228fcaeba51a3ec95905
Author: Eugene Burkov <e.burkov@adguard.com>
Date: Fri Dec 25 17:38:29 2020 +0300
util: simpl hosts upd algo
This commit is contained in:
parent
93ffed7809
commit
8a1d86aa7d
|
@ -29,10 +29,12 @@ type AutoHosts struct {
|
|||
// TODO(a.garipov): Make better use of newtypes. Perhaps a custom map.
|
||||
tableReverse map[string][]string
|
||||
|
||||
hostsFn string // path to the main hosts-file
|
||||
hostsDirs []string // paths to OS-specific directories with hosts-files
|
||||
watcher *fsnotify.Watcher // file and directory watcher object
|
||||
updateChan chan bool // signal for 'updateLoop' goroutine
|
||||
hostsFn string // path to the main hosts-file
|
||||
hostsDirs []string // paths to OS-specific directories with hosts-files
|
||||
watcher *fsnotify.Watcher // file and directory watcher object
|
||||
|
||||
// onlyWritesChan used to contain only writing events from watcher.
|
||||
onlyWritesChan chan fsnotify.Event
|
||||
|
||||
onChanged onChangedT // notification to other modules
|
||||
}
|
||||
|
@ -54,7 +56,7 @@ func (a *AutoHosts) notify() {
|
|||
// hostsFn: Override default name for the hosts-file (optional)
|
||||
func (a *AutoHosts) Init(hostsFn string) {
|
||||
a.table = make(map[string][]net.IP)
|
||||
a.updateChan = make(chan bool, 2)
|
||||
a.onlyWritesChan = make(chan fsnotify.Event, 2)
|
||||
|
||||
a.hostsFn = "/etc/hosts"
|
||||
if runtime.GOOS == "windows" {
|
||||
|
@ -82,8 +84,7 @@ func (a *AutoHosts) Init(hostsFn string) {
|
|||
func (a *AutoHosts) Start() {
|
||||
log.Debug("Start AutoHosts module")
|
||||
|
||||
go a.updateLoop()
|
||||
a.updateChan <- true
|
||||
a.updateHosts()
|
||||
|
||||
if a.watcher != nil {
|
||||
go a.watcherLoop()
|
||||
|
@ -104,11 +105,10 @@ func (a *AutoHosts) Start() {
|
|||
|
||||
// Close - close module
|
||||
func (a *AutoHosts) Close() {
|
||||
a.updateChan <- false
|
||||
close(a.updateChan)
|
||||
if a.watcher != nil {
|
||||
_ = a.watcher.Close()
|
||||
}
|
||||
close(a.onlyWritesChan)
|
||||
}
|
||||
|
||||
// Process returns the list of IP addresses for the hostname or nil if nothing
|
||||
|
@ -273,20 +273,32 @@ func (a *AutoHosts) load(table map[string][]net.IP, tableRev map[string][]string
|
|||
}
|
||||
}
|
||||
|
||||
// onlyWrites is a filter for (*fsnotify.Watcher).Events.
|
||||
func (a *AutoHosts) onlyWrites() {
|
||||
for event := range a.watcher.Events {
|
||||
if event.Op&fsnotify.Write == fsnotify.Write {
|
||||
a.onlyWritesChan <- event
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Receive notifications from fsnotify package
|
||||
func (a *AutoHosts) watcherLoop() {
|
||||
go a.onlyWrites()
|
||||
for {
|
||||
select {
|
||||
case event, ok := <-a.watcher.Events:
|
||||
case event, ok := <-a.onlyWritesChan:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
// Assume that we sometimes have the same event occurred
|
||||
// several times.
|
||||
repeat := true
|
||||
for repeat {
|
||||
select {
|
||||
case <-a.watcher.Events:
|
||||
// Skip this duplicating event
|
||||
case _, ok = <-a.onlyWritesChan:
|
||||
repeat = ok
|
||||
default:
|
||||
repeat = false
|
||||
}
|
||||
|
@ -294,12 +306,7 @@ func (a *AutoHosts) watcherLoop() {
|
|||
|
||||
if event.Op&fsnotify.Write == fsnotify.Write {
|
||||
log.Debug("AutoHosts: modified: %s", event.Name)
|
||||
select {
|
||||
case a.updateChan <- true:
|
||||
// sent a signal to 'updateLoop' goroutine
|
||||
default:
|
||||
// queue is full
|
||||
}
|
||||
a.updateHosts()
|
||||
}
|
||||
|
||||
case err, ok := <-a.watcher.Errors:
|
||||
|
@ -311,18 +318,6 @@ func (a *AutoHosts) watcherLoop() {
|
|||
}
|
||||
}
|
||||
|
||||
// updateLoop reads static hosts from system files.
|
||||
func (a *AutoHosts) updateLoop() {
|
||||
for ok := range a.updateChan {
|
||||
if !ok {
|
||||
log.Debug("Finished AutoHosts update loop")
|
||||
return
|
||||
}
|
||||
|
||||
a.updateHosts()
|
||||
}
|
||||
}
|
||||
|
||||
// updateHosts - loads system hosts
|
||||
func (a *AutoHosts) updateHosts() {
|
||||
table := make(map[string][]net.IP)
|
||||
|
|
Loading…
Reference in New Issue