From f25f776c9f9d6a0538cd9028d9d82fc6965d9123 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Fri, 11 Jan 2019 15:27:47 +0200 Subject: core, light: get rid of the dual mutexes, hard to reason with --- light/lightchain.go | 29 +++++++++++------------------ light/lightchain_test.go | 4 ++-- 2 files changed, 13 insertions(+), 20 deletions(-) (limited to 'light') diff --git a/light/lightchain.go b/light/lightchain.go index 8e2734c2d..de3d583c7 100644 --- a/light/lightchain.go +++ b/light/lightchain.go @@ -57,7 +57,6 @@ type LightChain struct { scope event.SubscriptionScope genesisBlock *types.Block - mu sync.RWMutex chainmu sync.RWMutex bodyCache *lru.Cache // Cache for the most recent block bodies @@ -165,8 +164,8 @@ func (self *LightChain) loadLastState() error { // SetHead rewinds the local chain to a new head. Everything above the new // head will be deleted and the new one set. func (bc *LightChain) SetHead(head uint64) { - bc.mu.Lock() - defer bc.mu.Unlock() + bc.chainmu.Lock() + defer bc.chainmu.Unlock() bc.hc.SetHead(head, nil) bc.loadLastState() @@ -188,8 +187,8 @@ func (bc *LightChain) ResetWithGenesisBlock(genesis *types.Block) { // Dump the entire block chain and purge the caches bc.SetHead(0) - bc.mu.Lock() - defer bc.mu.Unlock() + bc.chainmu.Lock() + defer bc.chainmu.Unlock() // Prepare the genesis block and reinitialise the chain rawdb.WriteTd(bc.chainDb, genesis.Hash(), genesis.NumberU64(), genesis.Difficulty()) @@ -315,8 +314,8 @@ func (bc *LightChain) Stop() { // Rollback is designed to remove a chain of links from the database that aren't // certain enough to be valid. func (self *LightChain) Rollback(chain []common.Hash) { - self.mu.Lock() - defer self.mu.Unlock() + self.chainmu.Lock() + defer self.chainmu.Unlock() for i := len(chain) - 1; i >= 0; i-- { hash := chain[i] @@ -362,19 +361,13 @@ func (self *LightChain) InsertHeaderChain(chain []*types.Header, checkFreq int) // Make sure only one thread manipulates the chain at once self.chainmu.Lock() - defer func() { - self.chainmu.Unlock() - time.Sleep(time.Millisecond * 10) // ugly hack; do not hog chain lock in case syncing is CPU-limited by validation - }() + defer self.chainmu.Unlock() self.wg.Add(1) defer self.wg.Done() var events []interface{} whFunc := func(header *types.Header) error { - self.mu.Lock() - defer self.mu.Unlock() - status, err := self.hc.WriteHeader(header) switch status { @@ -441,8 +434,8 @@ func (self *LightChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []c // // Note: ancestor == 0 returns the same block, 1 returns its parent and so on. func (bc *LightChain) GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) { - bc.chainmu.Lock() - defer bc.chainmu.Unlock() + bc.chainmu.RLock() + defer bc.chainmu.RUnlock() return bc.hc.GetAncestor(hash, number, ancestor, maxNonCanonical) } @@ -483,8 +476,8 @@ func (self *LightChain) SyncCht(ctx context.Context) bool { } // Retrieve the latest useful header and update to it if header, err := GetHeaderByNumber(ctx, self.odr, latest); header != nil && err == nil { - self.mu.Lock() - defer self.mu.Unlock() + self.chainmu.Lock() + defer self.chainmu.Unlock() // Ensure the chain didn't move past the latest block while retrieving it if self.hc.CurrentHeader().Number.Uint64() < header.Number.Uint64() { diff --git a/light/lightchain_test.go b/light/lightchain_test.go index d45c0656d..374cb5319 100644 --- a/light/lightchain_test.go +++ b/light/lightchain_test.go @@ -122,10 +122,10 @@ func testHeaderChainImport(chain []*types.Header, lightchain *LightChain) error return err } // Manually insert the header into the database, but don't reorganize (allows subsequent testing) - lightchain.mu.Lock() + lightchain.chainmu.Lock() rawdb.WriteTd(lightchain.chainDb, header.Hash(), header.Number.Uint64(), new(big.Int).Add(header.Difficulty, lightchain.GetTdByHash(header.ParentHash))) rawdb.WriteHeader(lightchain.chainDb, header) - lightchain.mu.Unlock() + lightchain.chainmu.Unlock() } return nil } -- cgit v1.2.3