From 8c3701c7c50a6344e7ceb24c2f357bd605184d49 Mon Sep 17 00:00:00 2001 From: zsfelfoldi Date: Wed, 29 Jun 2016 02:43:36 +0200 Subject: [PATCH] fixed fetcher semaphores --- les/fetcher.go | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/les/fetcher.go b/les/fetcher.go index ac6fb0021c..c18fdbfb33 100644 --- a/les/fetcher.go +++ b/les/fetcher.go @@ -20,6 +20,7 @@ package les import ( "fmt" "sync" + "sync/atomic" "time" "github.com/ethereum/go-ethereum/core" @@ -35,6 +36,7 @@ type lightFetcher struct{ syncPoolMu sync.Mutex syncPool map[*peer]struct{} syncPoolNotify chan struct{} + syncPoolNotified uint32 } func newLightFetcher(pm *ProtocolManager) *lightFetcher { @@ -85,7 +87,9 @@ func (f *lightFetcher) notify(p *peer, block blockInfo) { f.syncPoolMu.Lock() f.syncPool[p] = struct{}{} f.syncPoolMu.Unlock() - f.syncPoolNotify <- struct{}{} + if atomic.SwapUint32(&f.syncPoolNotified, 1) == 0 { + f.syncPoolNotify <- struct{}{} + } } } @@ -113,24 +117,32 @@ func (f *lightFetcher) fetchBestFromPool() *peer { } func (f *lightFetcher) syncLoop() { + f.pm.wg.Add(1) + defer f.pm.wg.Done() + for { select { case <-f.pm.quitSync: return case <-f.syncPoolNotify: + atomic.StoreUint32(&f.syncPoolNotified, 0) chn := f.pm.getSyncLock(false) if chn != nil { - go func() { - <-chn - f.syncPoolNotify <- struct{}{} - }() + if atomic.SwapUint32(&f.syncPoolNotified, 1) == 0 { + go func() { + <-chn + f.syncPoolNotify <- struct{}{} + }() + } } else { if p := f.fetchBestFromPool(); p != nil { go f.syncWithPeer(p) - go func() { - time.Sleep(softRequestTimeout) - f.syncPoolNotify <- struct{}{} - }() + if atomic.SwapUint32(&f.syncPoolNotified, 1) == 0 { + go func() { + time.Sleep(softRequestTimeout) + f.syncPoolNotify <- struct{}{} + }() + } } } }