diff --git a/les/freeclient.go b/les/freeclient.go index 4d1c83dd62..5ee607be8f 100644 --- a/les/freeclient.go +++ b/les/freeclient.go @@ -64,7 +64,7 @@ const ( ) // newFreeClientPool creates a new free client pool -func newFreeClientPool(db ethdb.Database, connectedLimit, totalLimit int, quit chan struct{}, wg *sync.WaitGroup, clock mclock.Clock) *freeClientPool { +func newFreeClientPool(db ethdb.Database, connectedLimit, totalLimit int, clock mclock.Clock) *freeClientPool { pool := &freeClientPool{ db: db, clock: clock, @@ -75,19 +75,16 @@ func newFreeClientPool(db ethdb.Database, connectedLimit, totalLimit int, quit c totalLimit: totalLimit, } pool.loadFromDb() - wg.Add(1) - go func() { - <-quit - pool.lock.Lock() - pool.closed = true - pool.saveToDb() - pool.lock.Unlock() - wg.Done() - }() - return pool } +func (f *freeClientPool) stop() { + f.lock.Lock() + f.closed = true + f.saveToDb() + f.lock.Unlock() +} + // connect should be called after a successful handshake. If the connection was // rejected, there is no need to call disconnect. // diff --git a/les/freeclient_test.go b/les/freeclient_test.go index f78a3dda8c..e95abc7aad 100644 --- a/les/freeclient_test.go +++ b/les/freeclient_test.go @@ -21,7 +21,6 @@ package les import ( "fmt" "math/rand" - "sync" "testing" "time" @@ -45,11 +44,9 @@ const testFreeClientPoolTicks = 500000 func testFreeClientPool(t *testing.T, connLimit, clientCount int) { var ( - quit = make(chan struct{}) clock mclock.Simulated - wg sync.WaitGroup db = ethdb.NewMemDatabase() - pool = newFreeClientPool(db, connLimit, 10000, quit, &wg, &clock) + pool = newFreeClientPool(db, connLimit, 10000, &clock) connected = make([]bool, clientCount) connTicks = make([]int, clientCount) disconnCh = make(chan int, clientCount) @@ -127,11 +124,8 @@ func testFreeClientPool(t *testing.T, connLimit, clientCount int) { } // close and restart pool - close(quit) - wg.Wait() - quit2 := make(chan struct{}) - var wg2 sync.WaitGroup - pool = newFreeClientPool(db, connLimit, 10000, quit2, &wg2, &clock) + pool.stop() + pool = newFreeClientPool(db, connLimit, 10000, &clock) // try connecting all known peers (connLimit should be filled up) for i := 0; i < clientCount; i++ { @@ -141,5 +135,5 @@ func testFreeClientPool(t *testing.T, connLimit, clientCount int) { if !pool.connect("newPeer2", func() {}) { t.Errorf("Previously unknown peer rejected after restarting pool") } - close(quit2) + pool.stop() } diff --git a/les/handler.go b/les/handler.go index fe9209dc94..7f370ed7cb 100644 --- a/les/handler.go +++ b/les/handler.go @@ -228,7 +228,7 @@ func (pm *ProtocolManager) Start(maxPeers int) { if pm.lightSync { go pm.syncer() } else { - pm.clientPool = newFreeClientPool(pm.chainDb, maxPeers, 10000, pm.quitSync, pm.wg, mclock.System{}) + pm.clientPool = newFreeClientPool(pm.chainDb, maxPeers, 10000, mclock.System{}) go func() { for range pm.newPeerCh { } @@ -246,6 +246,9 @@ func (pm *ProtocolManager) Stop() { pm.noMorePeers <- struct{}{} close(pm.quitSync) // quits syncer, fetcher + if pm.clientPool != nil { + pm.clientPool.stop() + } // Disconnect existing sessions. // This also closes the gate for any new registrations on the peer set.