core_tests: reset thread pool between tests

Avoids a DB error (leading to an assert) where a thread uses
a read txn previously created with an environment that was
since closed and reopened. While this usually works since
BlockchainLMDB renews txns if it detects the environment has
changed, this will not work if objects end up being allocated
at the same address as the previous instance, leading to stale
data usage.

Thanks hyc for the LMDB debugging.
pull/235/head
moneromooo-monero 5 years ago
parent a48ef0a65a
commit 27522aaa12
No known key found for this signature in database
GPG Key ID: 686F07454D6CEFC3

@ -37,16 +37,14 @@ static __thread bool is_leaf = false;
namespace tools
{
threadpool::threadpool(unsigned int max_threads) : running(true), active(0) {
boost::thread::attributes attrs;
attrs.set_stack_size(THREAD_STACK_SIZE);
max = max_threads ? max_threads : tools::get_max_concurrency();
size_t i = max ? max - 1 : 0;
while(i--) {
threads.push_back(boost::thread(attrs, boost::bind(&threadpool::run, this, false)));
}
create(max_threads);
}
threadpool::~threadpool() {
destroy();
}
void threadpool::destroy() {
try
{
const boost::unique_lock<boost::mutex> lock(mutex);
@ -64,6 +62,23 @@ threadpool::~threadpool() {
try { threads[i].join(); }
catch (...) { /* ignore */ }
}
threads.clear();
}
void threadpool::recycle() {
destroy();
create(max);
}
void threadpool::create(unsigned int max_threads) {
boost::thread::attributes attrs;
attrs.set_stack_size(THREAD_STACK_SIZE);
max = max_threads ? max_threads : tools::get_max_concurrency();
size_t i = max ? max - 1 : 0;
running = true;
while(i--) {
threads.push_back(boost::thread(attrs, boost::bind(&threadpool::run, this, false)));
}
}
void threadpool::submit(waiter *obj, std::function<void()> f, bool leaf) {

@ -69,12 +69,17 @@ public:
// task to finish.
void submit(waiter *waiter, std::function<void()> f, bool leaf = false);
// destroy and recreate threads
void recycle();
unsigned int get_max_concurrency() const;
~threadpool();
private:
threadpool(unsigned int max_threads = 0);
void destroy();
void create(unsigned int max_threads);
typedef struct entry {
waiter *wo;
std::function<void()> f;

@ -47,6 +47,7 @@
#include "include_base_utils.h"
#include "common/boost_serialization_helper.h"
#include "common/command_line.h"
#include "common/threadpool.h"
#include "cryptonote_basic/account_boost_serialization.h"
#include "cryptonote_basic/cryptonote_basic.h"
@ -758,6 +759,7 @@ inline bool do_replay_events_get_core(std::vector<test_event_entry>& events, cry
t_test_class validator;
bool ret = replay_events_through_core<t_test_class>(c, events, validator);
tools::threadpool::getInstance().recycle();
// c.deinit();
return ret;
}

Loading…
Cancel
Save