diff --git a/common/ledger/blkstorage/fsblkstorage/blocks_itr.go b/common/ledger/blkstorage/fsblkstorage/blocks_itr.go index 7ebe52af939..3e06887b639 100644 --- a/common/ledger/blkstorage/fsblkstorage/blocks_itr.go +++ b/common/ledger/blkstorage/fsblkstorage/blocks_itr.go @@ -92,11 +92,11 @@ func (itr *blocksItr) Next() (ledger.QueryResult, error) { // Close releases any resources held by the iterator func (itr *blocksItr) Close() { + itr.mgr.cpInfoCond.L.Lock() + defer itr.mgr.cpInfoCond.L.Unlock() itr.closeMarkerLock.Lock() defer itr.closeMarkerLock.Unlock() itr.closeMarker = true - itr.mgr.cpInfoCond.L.Lock() - defer itr.mgr.cpInfoCond.L.Unlock() itr.mgr.cpInfoCond.Broadcast() if itr.stream != nil { itr.stream.close() diff --git a/common/ledger/blkstorage/fsblkstorage/blocks_itr_test.go b/common/ledger/blkstorage/fsblkstorage/blocks_itr_test.go index 19111b73b00..e4c1234974b 100644 --- a/common/ledger/blkstorage/fsblkstorage/blocks_itr_test.go +++ b/common/ledger/blkstorage/fsblkstorage/blocks_itr_test.go @@ -75,6 +75,39 @@ func TestBlockItrClose(t *testing.T) { testutil.AssertNil(t, bh) } +func TestRaceToDeadlock(t *testing.T) { + env := newTestEnv(t, NewConf(testPath(), 0)) + defer env.Cleanup() + blkfileMgrWrapper := newTestBlockfileWrapper(env, "testLedger") + defer blkfileMgrWrapper.close() + blkfileMgr := blkfileMgrWrapper.blockfileMgr + + blocks := testutil.ConstructTestBlocks(t, 5) + blkfileMgrWrapper.addBlocks(blocks) + + for i := 0; i < 1000; i++ { + itr, err := blkfileMgr.retrieveBlocks(5) + if err != nil { + panic(err) + } + go func() { + itr.Next() + }() + itr.Close() + } + + for i := 0; i < 1000; i++ { + itr, err := blkfileMgr.retrieveBlocks(5) + if err != nil { + panic(err) + } + go func() { + itr.Close() + }() + itr.Next() + } +} + func TestBlockItrCloseWithoutRetrieve(t *testing.T) { env := newTestEnv(t, NewConf(testPath(), 0)) defer env.Cleanup()