Fixed global init/shutdown order

This commit is contained in:
SChernykh 2024-12-03 21:05:27 +01:00
parent ecdaa83669
commit 90dfc4d7aa
13 changed files with 89 additions and 41 deletions

View file

@ -209,7 +209,7 @@ static void do_status(p2pool *m_pool, const char * /* args */)
m_pool->print_merge_mining_status(); m_pool->print_merge_mining_status();
bkg_jobs_tracker.print_status(); bkg_jobs_tracker->print_status();
if (p2p) { if (p2p) {
p2p->check_for_updates(true); p2p->check_for_updates(true);
@ -313,7 +313,7 @@ static void do_stop_mining(p2pool* m_pool, const char* /*args*/)
static void do_exit(p2pool *m_pool, const char * /* args */) static void do_exit(p2pool *m_pool, const char * /* args */)
{ {
bkg_jobs_tracker.wait(); bkg_jobs_tracker->wait();
m_pool->stop(); m_pool->stop();
} }

View file

@ -37,9 +37,7 @@ class RandomBytes
public: public:
RandomBytes() : rng(RandomDeviceSeed::instance), dist(0, 255) RandomBytes() : rng(RandomDeviceSeed::instance), dist(0, 255)
{ {
if (uv_mutex_init(&m) != 0) { uv_mutex_init_checked(&m);
abort();
}
// Diffuse the initial state in case it has low quality // Diffuse the initial state in case it has low quality
rng.discard(10000); rng.discard(10000);
@ -66,7 +64,7 @@ private:
std::uniform_int_distribution<> dist; std::uniform_int_distribution<> dist;
}; };
static RandomBytes randomBytes; static RandomBytes* randomBytes = nullptr;
} }
@ -86,7 +84,7 @@ static FORCEINLINE bool less32(const uint8_t* k0, const uint8_t* k1)
void generate_keys(hash& pub, hash& sec) void generate_keys(hash& pub, hash& sec)
{ {
do { do {
do { randomBytes(sec.h); } while (!less32(sec.h, limit)); do { (*randomBytes)(sec.h); } while (!less32(sec.h, limit));
sc_reduce32(sec.h); sc_reduce32(sec.h);
} while (!sc_isnonzero(sec.h)); } while (!sc_isnonzero(sec.h));
@ -472,6 +470,10 @@ void derive_view_tag(const hash& derivation, size_t output_index, uint8_t& view_
void init_crypto_cache() void init_crypto_cache()
{ {
if (!randomBytes) {
randomBytes = new RandomBytes();
}
if (!cache) { if (!cache) {
cache = new Cache(); cache = new Cache();
} }
@ -479,6 +481,11 @@ void init_crypto_cache()
void destroy_crypto_cache() void destroy_crypto_cache()
{ {
if (randomBytes) {
delete randomBytes;
randomBytes = nullptr;
}
if (cache) { if (cache) {
delete cache; delete cache;
cache = nullptr; cache = nullptr;

View file

@ -122,7 +122,6 @@ public:
{ {
#if defined(_WIN32) && defined(_MSC_VER) && !defined(NDEBUG) #if defined(_WIN32) && defined(_MSC_VER) && !defined(NDEBUG)
SetUnhandledExceptionFilter(UnhandledExceptionFilter); SetUnhandledExceptionFilter(UnhandledExceptionFilter);
SymInitialize(GetCurrentProcess(), NULL, TRUE);
#endif #endif
set_main_thread(); set_main_thread();
@ -163,10 +162,8 @@ public:
CONSOLE_COLORS = false; CONSOLE_COLORS = false;
} }
LOGINFO(0, "started");
if (!m_logFile.is_open()) { if (!m_logFile.is_open()) {
LOGERR(0, "failed to open " << log_file_name); fprintf(stderr, "failed to open %s\n", log_file_name);
} }
init_uv_threadpool(); init_uv_threadpool();
@ -203,10 +200,6 @@ public:
#endif #endif
m_logFile.close(); m_logFile.close();
#if defined(_WIN32) && defined(_MSC_VER) && !defined(NDEBUG)
SymCleanup(GetCurrentProcess());
#endif
} }
FORCEINLINE void write(const char* buf, uint32_t size) FORCEINLINE void write(const char* buf, uint32_t size)
@ -252,13 +245,13 @@ private:
int err = putenv(buf); int err = putenv(buf);
if (err != 0) { if (err != 0) {
err = errno; err = errno;
LOGWARN(0, "Couldn't set UV thread pool size to " << N << " threads, putenv returned error " << err); fprintf(stderr, "Couldn't set UV thread pool size to %u threads, putenv returned error %d\n", N, err);
} }
static uv_work_t dummy; static uv_work_t dummy;
err = uv_queue_work(uv_default_loop_checked(), &dummy, [](uv_work_t*) {}, nullptr); err = uv_queue_work(uv_default_loop_checked(), &dummy, [](uv_work_t*) {}, nullptr);
if (err) { if (err) {
LOGERR(0, "init_uv_threadpool: uv_queue_work failed, error " << uv_err_name(err)); fprintf(stderr, "init_uv_threadpool: uv_queue_work failed, error %s\n", uv_err_name(err));
} }
} }
@ -398,7 +391,7 @@ private:
std::ofstream m_logFile; std::ofstream m_logFile;
}; };
static Worker worker; static Worker* worker = nullptr;
#endif // P2POOL_LOG_DISABLE #endif // P2POOL_LOG_DISABLE
@ -445,7 +438,16 @@ NOINLINE Writer::~Writer()
m_buf[2] = static_cast<uint8_t>(size >> 8); m_buf[2] = static_cast<uint8_t>(size >> 8);
m_buf[m_pos] = '\n'; m_buf[m_pos] = '\n';
#ifndef P2POOL_LOG_DISABLE #ifndef P2POOL_LOG_DISABLE
worker.write(m_buf, size); worker->write(m_buf, size);
#endif
}
void start()
{
#ifndef P2POOL_LOG_DISABLE
worker = new Worker();
LOGINFO(0, "started");
#endif #endif
} }
@ -458,7 +460,8 @@ void reopen()
void stop() void stop()
{ {
#ifndef P2POOL_LOG_DISABLE #ifndef P2POOL_LOG_DISABLE
worker.stop(); delete worker;
worker = nullptr;
#endif #endif
} }

View file

@ -547,6 +547,7 @@ struct DummyStream
#endif #endif
void start();
void reopen(); void reopen();
void stop(); void stop();

View file

@ -26,6 +26,14 @@
#include "randomx.h" #include "randomx.h"
#endif #endif
#if defined(_WIN32) && defined(_MSC_VER) && !defined(NDEBUG)
#include <DbgHelp.h>
#pragma comment(lib, "Dbghelp.lib")
#endif
void p2pool_usage() void p2pool_usage()
{ {
printf("P2Pool %s\n" printf("P2Pool %s\n"
@ -188,8 +196,14 @@ int main(int argc, char* argv[])
} }
} }
#if defined(_WIN32) && defined(_MSC_VER) && !defined(NDEBUG)
SymInitialize(GetCurrentProcess(), NULL, TRUE);
#endif
memory_tracking_start(); memory_tracking_start();
p2pool::log::start();
p2pool::init_crypto_cache(); p2pool::init_crypto_cache();
int result = static_cast<int>(curl_global_init_mem(CURL_GLOBAL_ALL, p2pool::malloc_hook, p2pool::free_hook, p2pool::realloc_hook, p2pool::strdup_hook, p2pool::calloc_hook)); int result = static_cast<int>(curl_global_init_mem(CURL_GLOBAL_ALL, p2pool::malloc_hook, p2pool::free_hook, p2pool::realloc_hook, p2pool::strdup_hook, p2pool::calloc_hook));
@ -209,9 +223,15 @@ int main(int argc, char* argv[])
p2pool::destroy_crypto_cache(); p2pool::destroy_crypto_cache();
p2pool::log::stop();
if (!memory_tracking_stop()) { if (!memory_tracking_stop()) {
result = 1; result = 1;
} }
#if defined(_WIN32) && defined(_MSC_VER) && !defined(NDEBUG)
SymCleanup(GetCurrentProcess());
#endif
return result; return result;
} }

View file

@ -79,7 +79,7 @@ struct TrackedAllocation
static_assert(sizeof(TrackedAllocation) == 256, ""); static_assert(sizeof(TrackedAllocation) == 256, "");
uv_mutex_t allocation_lock; std::mutex allocation_lock;
std::hash<void*> hasher; std::hash<void*> hasher;
uint32_t first[N]; uint32_t first[N];
uint32_t next[N]; uint32_t next[N];
@ -98,7 +98,7 @@ void show_top_10_allocations()
const HANDLE h = GetCurrentProcess(); const HANDLE h = GetCurrentProcess();
{ {
p2pool::MutexLock lock(allocation_lock); std::lock_guard<std::mutex> lock(allocation_lock);
TrackedAllocation* end = buf; TrackedAllocation* end = buf;
for (size_t i = 0; i < N; ++i) { for (size_t i = 0; i < N; ++i) {
@ -173,7 +173,7 @@ FORCEINLINE static void add_alocation(void* p, size_t size)
const size_t index = hasher(p) & (N - 1); const size_t index = hasher(p) & (N - 1);
p2pool::MutexLock lock(allocation_lock); std::lock_guard<std::mutex> lock(allocation_lock);
++num_allocations; ++num_allocations;
if (num_allocations >= N / 2) { if (num_allocations >= N / 2) {
@ -204,7 +204,7 @@ FORCEINLINE static void remove_allocation(void* p)
return; return;
} }
p2pool::MutexLock lock(allocation_lock); std::lock_guard<std::mutex> lock(allocation_lock);
--num_allocations; --num_allocations;
@ -295,7 +295,6 @@ void memory_tracking_start()
using namespace p2pool; using namespace p2pool;
uv_replace_allocator(malloc_hook, realloc_hook, calloc_hook, free_hook); uv_replace_allocator(malloc_hook, realloc_hook, calloc_hook, free_hook);
uv_mutex_init_checked(&allocation_lock);
track_memory = true; track_memory = true;
} }
@ -304,7 +303,6 @@ bool memory_tracking_stop()
using namespace p2pool; using namespace p2pool;
track_memory = false; track_memory = false;
uv_mutex_destroy(&allocation_lock);
const HANDLE h = GetCurrentProcess(); const HANDLE h = GetCurrentProcess();

View file

@ -73,6 +73,8 @@ p2pool::p2pool(int argc, char* argv[])
m_params = p; m_params = p;
bkg_jobs_tracker = new BackgroundJobTracker();
#ifdef WITH_UPNP #ifdef WITH_UPNP
if (p->m_upnp) { if (p->m_upnp) {
init_upnp(); init_upnp();
@ -184,6 +186,8 @@ p2pool::p2pool(int argc, char* argv[])
m_hasher = new RandomX_Hasher_RPC(this); m_hasher = new RandomX_Hasher_RPC(this);
#endif #endif
PoolBlock::s_precalculatedSharesLock = new ReadWriteLock();
m_blockTemplate = new BlockTemplate(m_sideChain, m_hasher); m_blockTemplate = new BlockTemplate(m_sideChain, m_hasher);
m_mempool = new Mempool(); m_mempool = new Mempool();
@ -232,6 +236,9 @@ p2pool::~p2pool()
delete m_blockTemplate; delete m_blockTemplate;
delete m_mempool; delete m_mempool;
delete m_params; delete m_params;
delete bkg_jobs_tracker;
delete PoolBlock::s_precalculatedSharesLock;
} }
void p2pool::update_host_ping(const std::string& display_name, double ping) void p2pool::update_host_ping(const std::string& display_name, double ping)
@ -1955,7 +1962,7 @@ int p2pool::run()
m_stopped = true; m_stopped = true;
bkg_jobs_tracker.wait(); bkg_jobs_tracker->wait();
#ifdef WITH_RANDOMX #ifdef WITH_RANDOMX
delete m_miner; delete m_miner;

View file

@ -29,7 +29,7 @@ LOG_CATEGORY(PoolBlock)
namespace p2pool { namespace p2pool {
ReadWriteLock PoolBlock::s_precalculatedSharesLock; ReadWriteLock* PoolBlock::s_precalculatedSharesLock = nullptr;
PoolBlock::PoolBlock() PoolBlock::PoolBlock()
: m_majorVersion(0) : m_majorVersion(0)
@ -118,7 +118,7 @@ PoolBlock& PoolBlock::operator=(const PoolBlock& b)
m_wantBroadcast = b.m_wantBroadcast; m_wantBroadcast = b.m_wantBroadcast;
m_precalculated = b.m_precalculated; m_precalculated = b.m_precalculated;
{ {
WriteLock lock(s_precalculatedSharesLock); WriteLock lock(*s_precalculatedSharesLock);
m_precalculatedShares = b.m_precalculatedShares; m_precalculatedShares = b.m_precalculatedShares;
} }
@ -309,7 +309,7 @@ void PoolBlock::reset_offchain_data()
m_precalculated = false; m_precalculated = false;
{ {
WriteLock lock(s_precalculatedSharesLock); WriteLock lock(*s_precalculatedSharesLock);
m_precalculatedShares.clear(); m_precalculatedShares.clear();
m_precalculatedShares.shrink_to_fit(); m_precalculatedShares.shrink_to_fit();
} }

View file

@ -162,7 +162,7 @@ struct PoolBlock
bool m_precalculated; bool m_precalculated;
static ReadWriteLock s_precalculatedSharesLock; static ReadWriteLock* s_precalculatedSharesLock;
std::vector<MinerShare> m_precalculatedShares; std::vector<MinerShare> m_precalculatedShares;
uint64_t m_localTimestamp; uint64_t m_localTimestamp;

View file

@ -1683,7 +1683,7 @@ void SideChain::verify(PoolBlock* block)
std::vector<MinerShare> shares; std::vector<MinerShare> shares;
if (block->m_precalculated) { if (block->m_precalculated) {
WriteLock lock(PoolBlock::s_precalculatedSharesLock); WriteLock lock(*PoolBlock::s_precalculatedSharesLock);
shares = std::move(block->m_precalculatedShares); shares = std::move(block->m_precalculatedShares);
} }
@ -2356,7 +2356,7 @@ void SideChain::launch_precalc(const PoolBlock* block)
if (get_shares(b, shares, nullptr, true)) { if (get_shares(b, shares, nullptr, true)) {
b->m_precalculated = true; b->m_precalculated = true;
{ {
WriteLock lock(PoolBlock::s_precalculatedSharesLock); WriteLock lock(*PoolBlock::s_precalculatedSharesLock);
b->m_precalculatedShares = std::move(shares); b->m_precalculatedShares = std::move(shares);
} }
{ {
@ -2401,7 +2401,7 @@ void SideChain::precalc_worker()
wallets.clear(); wallets.clear();
ReadLock lock2(PoolBlock::s_precalculatedSharesLock); ReadLock lock2(*PoolBlock::s_precalculatedSharesLock);
const size_t n = job->m_precalculatedShares.size(); const size_t n = job->m_precalculatedShares.size();

View file

@ -452,7 +452,7 @@ void BackgroundJobTracker::print_status()
m_impl->print_status(); m_impl->print_status();
} }
BackgroundJobTracker bkg_jobs_tracker; BackgroundJobTracker* bkg_jobs_tracker = nullptr;
static thread_local bool main_thread = false; static thread_local bool main_thread = false;
void set_main_thread() { main_thread = true; } void set_main_thread() { main_thread = true; }

View file

@ -233,10 +233,10 @@ private:
Impl* m_impl; Impl* m_impl;
}; };
extern BackgroundJobTracker bkg_jobs_tracker; extern BackgroundJobTracker* bkg_jobs_tracker;
#define BACKGROUND_JOB_START(x) do { bkg_jobs_tracker.start(#x); } while (0) #define BACKGROUND_JOB_START(x) do { bkg_jobs_tracker->start(#x); } while (0)
#define BACKGROUND_JOB_STOP(x) do { bkg_jobs_tracker.stop(#x); } while (0) #define BACKGROUND_JOB_STOP(x) do { bkg_jobs_tracker->stop(#x); } while (0)
void set_main_thread(); void set_main_thread();
bool is_main_thread(); bool is_main_thread();

View file

@ -15,14 +15,26 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "common.h"
#include "util.h"
#include "pool_block.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
void p2pool_usage() {} void p2pool_usage() {}
namespace p2pool { void set_main_thread(); }
using namespace p2pool;
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
p2pool::set_main_thread(); set_main_thread();
PoolBlock::s_precalculatedSharesLock = new ReadWriteLock();
testing::InitGoogleTest(&argc, argv); testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS(); const int result = RUN_ALL_TESTS();
delete PoolBlock::s_precalculatedSharesLock;
return result;
} }