diff --git a/config/config.json b/config/config.json index 8b34dcb..bf57433 100755 --- a/config/config.json +++ b/config/config.json @@ -56,7 +56,7 @@ "blocks_search_lookahead" : 200, "search_thread_life_in_seconds" : 120, "max_number_of_blocks_to_import" : 132000, - "mysql_ping_every_seconds" : 300, + "mysql_ping_every_seconds" : 10, "ssl" : { "enable" : false, diff --git a/main.cpp b/main.cpp index 062ea62..4cf179d 100755 --- a/main.cpp +++ b/main.cpp @@ -15,6 +15,23 @@ using namespace restbed; using boost::filesystem::path; +// signal exit handler, addpated from aleth +class ExitHandler +{ +public: + + static void exitHandler(int) { s_shouldExit = true; } + + bool shouldExit() const { return s_shouldExit; } + +private: + static atomic s_shouldExit; + //Service& restbed_service; +}; + +atomic ExitHandler::s_shouldExit {false}; + + int main(int ac, const char* av[]) { @@ -125,10 +142,11 @@ if (!current_bc_status->init_monero_blockchain()) // by tx searching threads that are launched for each user independently, // when they log back or create new account. -xmreg::ThreadRAII blockchain_monitoring_thread( - std::thread([current_bc_status] - {current_bc_status->monitor_blockchain();}), - xmreg::ThreadRAII::DtorAction::join); +std::thread blockchain_monitoring_thread( + [¤t_bc_status]() +{ + current_bc_status->monitor_blockchain(); +}); OMINFO << "Blockchain monitoring thread started"; @@ -171,9 +189,12 @@ xmreg::MysqlPing mysql_ping { mysql_accounts->get_connection(), bc_setup.mysql_ping_every}; -xmreg::ThreadRAII mysql_ping_thread( - std::thread(std::ref(mysql_ping)), - xmreg::ThreadRAII::DtorAction::join); +std::thread mysql_ping_thread( + [&mysql_ping]() +{ + mysql_ping(); +}); + OMINFO << "MySQL ping thread started"; @@ -241,8 +262,52 @@ else OMINFO << "Start the service at http://127.0.0.1:" << app_port; } +//ExitHandler exitHandler(service); + +ExitHandler exitHandler; + +signal(SIGABRT, ExitHandler::exitHandler); +signal(SIGTERM, ExitHandler::exitHandler); +signal(SIGINT, ExitHandler::exitHandler); + + +std::thread restbed_service( + [&service, &settings]() +{ + OMINFO << "Starting restbed service thread."; + service.start(settings); +}); + + + + +// we are going to loop here for as long +// as control+c has been pressed +while (!exitHandler.shouldExit()) +{ + this_thread::sleep_for(100ms); +}; + +////////////////////////////////////////////// +// Try to greacfully stop all threads/services +////////////////////////////////////////////// + +OMINFO << "Stopping restbed service."; +service.stop(); +restbed_service.join(); + +OMINFO << "Stoppping blockchain_monitoring_thread. Please wait."; +current_bc_status->stop(); +blockchain_monitoring_thread.join(); + +OMINFO << "Stoppping mysql_ping. Please wait."; +mysql_ping.stop(); +mysql_ping_thread.join(); + +OMINFO << "Disconnecting from database."; +mysql_accounts->disconnect(); -service.start(settings); +OMINFO << "All done. Bye."; return EXIT_SUCCESS; } diff --git a/src/CurrentBlockchainStatus.cpp b/src/CurrentBlockchainStatus.cpp index 27a059c..919f9c6 100755 --- a/src/CurrentBlockchainStatus.cpp +++ b/src/CurrentBlockchainStatus.cpp @@ -35,9 +35,14 @@ CurrentBlockchainStatus::monitor_blockchain() is_running = true; while (true) - { + { if (stop_blockchain_monitor_loop) + { + stop_search_threads(); + clean_search_thread_map(); + OMINFO << "Breaking monitor_blockchain thread loop."; break; + } update_current_blockchain_height(); @@ -54,6 +59,8 @@ CurrentBlockchainStatus::monitor_blockchain() is_running = false; } + + OMINFO << "Exiting monitor_blockchain thread loop."; } uint64_t @@ -897,6 +904,17 @@ CurrentBlockchainStatus::clean_search_thread_map() } } +void +CurrentBlockchainStatus::stop_search_threads() +{ + std::lock_guard lck (searching_threads_map_mtx); + + for (auto& st: searching_threads) + { + st.second.get_functor().stop(); + } +} + tuple CurrentBlockchainStatus::construct_output_rct_field( const uint64_t global_amount_index, diff --git a/src/CurrentBlockchainStatus.h b/src/CurrentBlockchainStatus.h index 1d983fd..b295965 100755 --- a/src/CurrentBlockchainStatus.h +++ b/src/CurrentBlockchainStatus.h @@ -228,6 +228,9 @@ public: virtual void clean_search_thread_map(); + virtual void + stop_search_threads(); + /* * The frontend requires rct field to work * the filed consisitct of rct_pk, mask, and amount. @@ -264,6 +267,9 @@ public: virtual TxSearch& get_search_thread(string const& acc_address); + inline virtual void + stop() {stop_blockchain_monitor_loop = true;} + // default destructor is fine virtual ~CurrentBlockchainStatus() = default; diff --git a/src/MicroCore.cpp b/src/MicroCore.cpp index 4058b0b..ed97ed4 100755 --- a/src/MicroCore.cpp +++ b/src/MicroCore.cpp @@ -224,18 +224,18 @@ MicroCore::init_success() const return initialization_succeded; } -MicroCore::~MicroCore() -{ - //cout << "\n\nMicroCore::~MicroCore()\n\n"; - - if (initialization_succeded) - { - //core_storage.get_db().safesyncmode(true); - if (core_storage.get_db().is_open()) - core_storage.get_db().close(); - //cout << "\n\n core_storage.get_db().close();;\n\n"; - } - -} +//MicroCore::~MicroCore() +//{ +// //cout << "\n\nMicroCore::~MicroCore()\n\n"; + +// if (initialization_succeded) +// { +// //core_storage.get_db().safesyncmode(true); +// if (core_storage.get_db().is_open()) +// core_storage.get_db().close(); +// //cout << "\n\n core_storage.get_db().close();;\n\n"; +// } + +//} } diff --git a/src/MicroCore.h b/src/MicroCore.h index 896ea5c..71cbd51 100755 --- a/src/MicroCore.h +++ b/src/MicroCore.h @@ -212,11 +212,10 @@ public: secret_key); } - virtual bool init_success() const; - virtual ~MicroCore(); + virtual ~MicroCore() = default; }; } diff --git a/src/ThreadRAII.cpp b/src/ThreadRAII.cpp index 13eacbb..f7b6c3e 100755 --- a/src/ThreadRAII.cpp +++ b/src/ThreadRAII.cpp @@ -17,13 +17,15 @@ ThreadRAII::~ThreadRAII() { if (action == DtorAction::join) { - //std::cout << "\nThreadRAII::~ThreadRAII() t.join()\n"; + //std::cout << "\nThreadRAII::~ThreadRAII() t.join()\n" + // << std::endl; t.join(); } else { - t.detach(); - //std::cout << "\nThreadRAII::~ThreadRAII() t.detach()\n"; + //std::cout << "\nThreadRAII::~ThreadRAII() t.detach()\n" + // << std::endl; + t.detach(); } } } diff --git a/src/ThreadRAII.h b/src/ThreadRAII.h index 88126e3..e2b7921 100755 --- a/src/ThreadRAII.h +++ b/src/ThreadRAII.h @@ -15,7 +15,7 @@ namespace xmreg class ThreadRAII { public: - enum class DtorAction { join, detach}; + enum class DtorAction {join, detach}; ThreadRAII(std::thread&& _t, DtorAction _action); diff --git a/src/TxSearch.cpp b/src/TxSearch.cpp index fc4f057..de72eaf 100755 --- a/src/TxSearch.cpp +++ b/src/TxSearch.cpp @@ -67,6 +67,8 @@ TxSearch::operator()() auto current_bc_status_ptr = current_bc_status.get(); + searching_is_ongoing = true; + // we put everything in massive catch, as there are plenty ways in which // an exceptions can be thrown here. Mostly from mysql. // but because this is detatch thread, we cant catch them in main thread. @@ -75,7 +77,8 @@ TxSearch::operator()() try { while(continue_search) - { + { + seconds loop_timestamp {current_timestamp}; uint64_t last_block_height = current_bc_status->current_height; @@ -604,16 +607,18 @@ TxSearch::operator()() set_exception_ptr(); } + searching_is_ongoing = false; + // it will stop anyway, but just call it so we get info message pritened out stop(); + + } void TxSearch::stop() { - OMINFO << address_prefix + ": stopping the thread " - "by setting " - "continue_search=false"; + OMINFO << address_prefix + ": stopping the thread"; continue_search = false; } @@ -655,7 +660,7 @@ TxSearch::ping() bool TxSearch::still_searching() const { - return continue_search; + return searching_is_ongoing; } void diff --git a/src/TxSearch.h b/src/TxSearch.h index 2bccaa6..4ea0a99 100755 --- a/src/TxSearch.h +++ b/src/TxSearch.h @@ -45,8 +45,13 @@ private: // using the service. static seconds thread_search_life; + // indicate that a thread loop should keep running bool continue_search {true}; + // this acctually indicates whether thread loop finished + // its execution + bool searching_is_ongoing {false}; + // to store last exception thrown in the search thread // using this, a main thread can get info what went wrong here std::exception_ptr eptr; diff --git a/src/db/MysqlPing.cpp b/src/db/MysqlPing.cpp index 1539833..a841ec7 100755 --- a/src/db/MysqlPing.cpp +++ b/src/db/MysqlPing.cpp @@ -44,6 +44,8 @@ MysqlPing::operator()() ++counter; } + + OMINFO << "Exiting Mysql ping thread loop."; } }