Additional fix for core_tests

Reset thread-local info if it doesn't match the current env.
Only happens when a process opens/closes env multiple times in the
same process, doesn't affect monerod.
This commit is contained in:
Howard Chu 2017-12-28 20:24:08 +00:00
parent d52b732efb
commit 294adc8341
No known key found for this signature in database
GPG Key ID: FD2A70B44AB11BA7

View File

@ -2738,29 +2738,34 @@ void BlockchainLMDB::set_batch_transactions(bool batch_transactions)
bool BlockchainLMDB::block_rtxn_start(MDB_txn **mtxn, mdb_txn_cursors **mcur) const bool BlockchainLMDB::block_rtxn_start(MDB_txn **mtxn, mdb_txn_cursors **mcur) const
{ {
bool ret = false; bool ret = false;
mdb_threadinfo *tinfo;
if (m_write_txn && m_writer == boost::this_thread::get_id()) { if (m_write_txn && m_writer == boost::this_thread::get_id()) {
*mtxn = m_write_txn->m_txn; *mtxn = m_write_txn->m_txn;
*mcur = (mdb_txn_cursors *)&m_wcursors; *mcur = (mdb_txn_cursors *)&m_wcursors;
return ret; return ret;
} }
if (!m_tinfo.get()) /* Check for existing info and force reset if env doesn't match -
* only happens if env was opened/closed multiple times in same process
*/
if (!(tinfo = m_tinfo.get()) || mdb_txn_env(tinfo->m_ti_rtxn) != m_env)
{ {
m_tinfo.reset(new mdb_threadinfo); tinfo = new mdb_threadinfo;
memset(&m_tinfo->m_ti_rcursors, 0, sizeof(m_tinfo->m_ti_rcursors)); m_tinfo.reset(tinfo);
memset(&m_tinfo->m_ti_rflags, 0, sizeof(m_tinfo->m_ti_rflags)); memset(&tinfo->m_ti_rcursors, 0, sizeof(tinfo->m_ti_rcursors));
if (auto mdb_res = lmdb_txn_begin(m_env, NULL, MDB_RDONLY, &m_tinfo->m_ti_rtxn)) memset(&tinfo->m_ti_rflags, 0, sizeof(tinfo->m_ti_rflags));
if (auto mdb_res = lmdb_txn_begin(m_env, NULL, MDB_RDONLY, &tinfo->m_ti_rtxn))
throw0(DB_ERROR_TXN_START(lmdb_error("Failed to create a read transaction for the db: ", mdb_res).c_str())); throw0(DB_ERROR_TXN_START(lmdb_error("Failed to create a read transaction for the db: ", mdb_res).c_str()));
ret = true; ret = true;
} else if (!m_tinfo->m_ti_rflags.m_rf_txn) } else if (!tinfo->m_ti_rflags.m_rf_txn)
{ {
if (auto mdb_res = lmdb_txn_renew(m_tinfo->m_ti_rtxn)) if (auto mdb_res = lmdb_txn_renew(tinfo->m_ti_rtxn))
throw0(DB_ERROR_TXN_START(lmdb_error("Failed to renew a read transaction for the db: ", mdb_res).c_str())); throw0(DB_ERROR_TXN_START(lmdb_error("Failed to renew a read transaction for the db: ", mdb_res).c_str()));
ret = true; ret = true;
} }
if (ret) if (ret)
m_tinfo->m_ti_rflags.m_rf_txn = true; tinfo->m_ti_rflags.m_rf_txn = true;
*mtxn = m_tinfo->m_ti_rtxn; *mtxn = tinfo->m_ti_rtxn;
*mcur = &m_tinfo->m_ti_rcursors; *mcur = &tinfo->m_ti_rcursors;
if (ret) if (ret)
LOG_PRINT_L3("BlockchainLMDB::" << __func__); LOG_PRINT_L3("BlockchainLMDB::" << __func__);