mirror of
https://git.wownero.com/wownero/wownero.git
synced 2024-08-15 01:03:23 +00:00
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.
This commit is contained in:
parent
a48ef0a65a
commit
27522aaa12
3 changed files with 29 additions and 7 deletions
|
@ -37,16 +37,14 @@ static __thread bool is_leaf = false;
|
||||||
namespace tools
|
namespace tools
|
||||||
{
|
{
|
||||||
threadpool::threadpool(unsigned int max_threads) : running(true), active(0) {
|
threadpool::threadpool(unsigned int max_threads) : running(true), active(0) {
|
||||||
boost::thread::attributes attrs;
|
create(max_threads);
|
||||||
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)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
threadpool::~threadpool() {
|
threadpool::~threadpool() {
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void threadpool::destroy() {
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const boost::unique_lock<boost::mutex> lock(mutex);
|
const boost::unique_lock<boost::mutex> lock(mutex);
|
||||||
|
@ -64,6 +62,23 @@ threadpool::~threadpool() {
|
||||||
try { threads[i].join(); }
|
try { threads[i].join(); }
|
||||||
catch (...) { /* ignore */ }
|
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) {
|
void threadpool::submit(waiter *obj, std::function<void()> f, bool leaf) {
|
||||||
|
|
|
@ -69,12 +69,17 @@ public:
|
||||||
// task to finish.
|
// task to finish.
|
||||||
void submit(waiter *waiter, std::function<void()> f, bool leaf = false);
|
void submit(waiter *waiter, std::function<void()> f, bool leaf = false);
|
||||||
|
|
||||||
|
// destroy and recreate threads
|
||||||
|
void recycle();
|
||||||
|
|
||||||
unsigned int get_max_concurrency() const;
|
unsigned int get_max_concurrency() const;
|
||||||
|
|
||||||
~threadpool();
|
~threadpool();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
threadpool(unsigned int max_threads = 0);
|
threadpool(unsigned int max_threads = 0);
|
||||||
|
void destroy();
|
||||||
|
void create(unsigned int max_threads);
|
||||||
typedef struct entry {
|
typedef struct entry {
|
||||||
waiter *wo;
|
waiter *wo;
|
||||||
std::function<void()> f;
|
std::function<void()> f;
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
#include "include_base_utils.h"
|
#include "include_base_utils.h"
|
||||||
#include "common/boost_serialization_helper.h"
|
#include "common/boost_serialization_helper.h"
|
||||||
#include "common/command_line.h"
|
#include "common/command_line.h"
|
||||||
|
#include "common/threadpool.h"
|
||||||
|
|
||||||
#include "cryptonote_basic/account_boost_serialization.h"
|
#include "cryptonote_basic/account_boost_serialization.h"
|
||||||
#include "cryptonote_basic/cryptonote_basic.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;
|
t_test_class validator;
|
||||||
bool ret = replay_events_through_core<t_test_class>(c, events, validator);
|
bool ret = replay_events_through_core<t_test_class>(c, events, validator);
|
||||||
|
tools::threadpool::getInstance().recycle();
|
||||||
// c.deinit();
|
// c.deinit();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue