wallet: cancellable refresh
^C while in manual refresh will cancel the refresh, since that's often an annoying thing to have to wait for. Also, a manual refresh command will interrupt any running background refresh and take over, rather than wait for the background refresh to be done, and look to be hanging.
This commit is contained in:
parent
8289975e22
commit
d68a63e404
|
@ -48,7 +48,7 @@ using namespace epee;
|
||||||
|
|
||||||
namespace tools
|
namespace tools
|
||||||
{
|
{
|
||||||
std::function<void(void)> signal_handler::m_handler;
|
std::function<void(int)> signal_handler::m_handler;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
std::string get_windows_version_display_string()
|
std::string get_windows_version_display_string()
|
||||||
|
|
|
@ -130,7 +130,7 @@ namespace tools
|
||||||
{
|
{
|
||||||
if (CTRL_C_EVENT == type || CTRL_BREAK_EVENT == type)
|
if (CTRL_C_EVENT == type || CTRL_BREAK_EVENT == type)
|
||||||
{
|
{
|
||||||
handle_signal();
|
handle_signal(type);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -141,21 +141,21 @@ namespace tools
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/*! \brief handler for NIX */
|
/*! \brief handler for NIX */
|
||||||
static void posix_handler(int /*type*/)
|
static void posix_handler(int type)
|
||||||
{
|
{
|
||||||
handle_signal();
|
handle_signal(type);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*! \brief calles m_handler */
|
/*! \brief calles m_handler */
|
||||||
static void handle_signal()
|
static void handle_signal(int type)
|
||||||
{
|
{
|
||||||
static std::mutex m_mutex;
|
static std::mutex m_mutex;
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::unique_lock<std::mutex> lock(m_mutex);
|
||||||
m_handler();
|
m_handler(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief where the installed handler is stored */
|
/*! \brief where the installed handler is stored */
|
||||||
static std::function<void(void)> m_handler;
|
static std::function<void(int)> m_handler;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -468,6 +468,7 @@ simple_wallet::simple_wallet()
|
||||||
, m_refresh_progress_reporter(*this)
|
, m_refresh_progress_reporter(*this)
|
||||||
, m_auto_refresh_run(false)
|
, m_auto_refresh_run(false)
|
||||||
, m_auto_refresh_refreshing(false)
|
, m_auto_refresh_refreshing(false)
|
||||||
|
, m_in_manual_refresh(false)
|
||||||
{
|
{
|
||||||
m_cmd_binder.set_handler("start_mining", boost::bind(&simple_wallet::start_mining, this, _1), tr("start_mining [<number_of_threads>] - Start mining in daemon"));
|
m_cmd_binder.set_handler("start_mining", boost::bind(&simple_wallet::start_mining, this, _1), tr("start_mining [<number_of_threads>] - Start mining in daemon"));
|
||||||
m_cmd_binder.set_handler("stop_mining", boost::bind(&simple_wallet::stop_mining, this, _1), tr("Stop mining in daemon"));
|
m_cmd_binder.set_handler("stop_mining", boost::bind(&simple_wallet::stop_mining, this, _1), tr("Stop mining in daemon"));
|
||||||
|
@ -1071,7 +1072,6 @@ bool simple_wallet::open_wallet(const string &wallet_file, const std::string& pa
|
||||||
|
|
||||||
m_wallet->init(m_daemon_address);
|
m_wallet->init(m_daemon_address);
|
||||||
|
|
||||||
refresh(std::vector<std::string>());
|
|
||||||
success_msg_writer() <<
|
success_msg_writer() <<
|
||||||
"**********************************************************************\n" <<
|
"**********************************************************************\n" <<
|
||||||
tr("Use \"help\" command to see the list of available commands.\n") <<
|
tr("Use \"help\" command to see the list of available commands.\n") <<
|
||||||
|
@ -1084,6 +1084,11 @@ bool simple_wallet::close_wallet()
|
||||||
if (m_auto_refresh_run.load(std::memory_order_relaxed))
|
if (m_auto_refresh_run.load(std::memory_order_relaxed))
|
||||||
{
|
{
|
||||||
m_auto_refresh_run.store(false, std::memory_order_relaxed);
|
m_auto_refresh_run.store(false, std::memory_order_relaxed);
|
||||||
|
m_wallet->stop();
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(m_auto_refresh_mutex);
|
||||||
|
m_auto_refresh_cond.notify_one();
|
||||||
|
}
|
||||||
m_auto_refresh_thread.join();
|
m_auto_refresh_thread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1276,11 +1281,16 @@ void simple_wallet::on_skip_transaction(uint64_t height, const cryptonote::trans
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
bool simple_wallet::refresh(const std::vector<std::string>& args)
|
bool simple_wallet::refresh(const std::vector<std::string>& args)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(m_auto_refresh_mutex);
|
|
||||||
|
|
||||||
if (!try_connect_to_daemon())
|
if (!try_connect_to_daemon())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
bool auto_refresh_run = m_auto_refresh_run.load(std::memory_order_relaxed);
|
||||||
|
m_auto_refresh_run.store(false, std::memory_order_relaxed);
|
||||||
|
// stop any background refresh, and take over
|
||||||
|
m_wallet->stop();
|
||||||
|
std::unique_lock<std::mutex> lock(m_auto_refresh_mutex);
|
||||||
|
m_auto_refresh_cond.notify_one();
|
||||||
|
|
||||||
message_writer() << tr("Starting refresh...");
|
message_writer() << tr("Starting refresh...");
|
||||||
|
|
||||||
uint64_t fetched_blocks = 0;
|
uint64_t fetched_blocks = 0;
|
||||||
|
@ -1300,7 +1310,9 @@ bool simple_wallet::refresh(const std::vector<std::string>& args)
|
||||||
std::ostringstream ss;
|
std::ostringstream ss;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
m_in_manual_refresh.store(true, std::memory_order_relaxed);
|
||||||
m_wallet->refresh(start_height, fetched_blocks);
|
m_wallet->refresh(start_height, fetched_blocks);
|
||||||
|
m_in_manual_refresh.store(false, std::memory_order_relaxed);
|
||||||
ok = true;
|
ok = true;
|
||||||
// Clear line "Height xxx of xxx"
|
// Clear line "Height xxx of xxx"
|
||||||
std::cout << "\r \r";
|
std::cout << "\r \r";
|
||||||
|
@ -1346,6 +1358,8 @@ bool simple_wallet::refresh(const std::vector<std::string>& args)
|
||||||
fail_msg_writer() << tr("refresh failed: ") << ss.str() << ". " << tr("Blocks received: ") << fetched_blocks;
|
fail_msg_writer() << tr("refresh failed: ") << ss.str() << ". " << tr("Blocks received: ") << fetched_blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_in_manual_refresh.store(false, std::memory_order_relaxed);
|
||||||
|
m_auto_refresh_run.store(auto_refresh_run, std::memory_order_relaxed);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
@ -2222,6 +2236,8 @@ void simple_wallet::wallet_refresh_thread()
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(m_auto_refresh_mutex);
|
std::unique_lock<std::mutex> lock(m_auto_refresh_mutex);
|
||||||
|
if (!m_auto_refresh_run.load(std::memory_order_relaxed))
|
||||||
|
break;
|
||||||
m_auto_refresh_refreshing = true;
|
m_auto_refresh_refreshing = true;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -2230,9 +2246,9 @@ void simple_wallet::wallet_refresh_thread()
|
||||||
}
|
}
|
||||||
catch(...) {}
|
catch(...) {}
|
||||||
m_auto_refresh_refreshing = false;
|
m_auto_refresh_refreshing = false;
|
||||||
m_auto_refresh_cond.wait_for(lock, chrono::seconds(90));
|
|
||||||
if (!m_auto_refresh_run.load(std::memory_order_relaxed))
|
if (!m_auto_refresh_run.load(std::memory_order_relaxed))
|
||||||
break;
|
break;
|
||||||
|
m_auto_refresh_cond.wait_for(lock, chrono::seconds(90));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
@ -2244,6 +2260,10 @@ bool simple_wallet::run()
|
||||||
{
|
{
|
||||||
m_auto_refresh_thread = std::thread([&]{wallet_refresh_thread();});
|
m_auto_refresh_thread = std::thread([&]{wallet_refresh_thread();});
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
refresh(std::vector<std::string>());
|
||||||
|
}
|
||||||
return m_cmd_binder.run_handling(std::string("[") + tr("wallet") + " " + addr_start + "]: ", "");
|
return m_cmd_binder.run_handling(std::string("[") + tr("wallet") + " " + addr_start + "]: ", "");
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
@ -2306,6 +2326,18 @@ bool simple_wallet::process_command(const std::vector<std::string> &args)
|
||||||
return m_cmd_binder.process_command_vec(args);
|
return m_cmd_binder.process_command_vec(args);
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
void simple_wallet::interrupt()
|
||||||
|
{
|
||||||
|
if (m_in_manual_refresh.load(std::memory_order_relaxed))
|
||||||
|
{
|
||||||
|
m_wallet->stop();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------------------------
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
@ -2480,7 +2512,7 @@ int main(int argc, char* argv[])
|
||||||
bool r = wrpc.init(vm);
|
bool r = wrpc.init(vm);
|
||||||
CHECK_AND_ASSERT_MES(r, 1, sw::tr("Failed to initialize wallet rpc server"));
|
CHECK_AND_ASSERT_MES(r, 1, sw::tr("Failed to initialize wallet rpc server"));
|
||||||
|
|
||||||
tools::signal_handler::install([&wrpc, &wal] {
|
tools::signal_handler::install([&wrpc, &wal](int) {
|
||||||
wrpc.send_stop_signal();
|
wrpc.send_stop_signal();
|
||||||
wal.store();
|
wal.store();
|
||||||
});
|
});
|
||||||
|
@ -2513,8 +2545,16 @@ int main(int argc, char* argv[])
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tools::signal_handler::install([&w] {
|
tools::signal_handler::install([&w](int type) {
|
||||||
w.stop();
|
if (type == SIGINT)
|
||||||
|
{
|
||||||
|
// if we're pressing ^C when refreshing, just stop refreshing
|
||||||
|
w.interrupt();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
w.stop();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
w.run();
|
w.run();
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,7 @@ namespace cryptonote
|
||||||
bool deinit();
|
bool deinit();
|
||||||
bool run();
|
bool run();
|
||||||
void stop();
|
void stop();
|
||||||
|
void interrupt();
|
||||||
|
|
||||||
//wallet *create_wallet();
|
//wallet *create_wallet();
|
||||||
bool process_command(const std::vector<std::string> &args);
|
bool process_command(const std::vector<std::string> &args);
|
||||||
|
@ -134,6 +135,7 @@ namespace cryptonote
|
||||||
uint64_t get_daemon_blockchain_height(std::string& err);
|
uint64_t get_daemon_blockchain_height(std::string& err);
|
||||||
bool try_connect_to_daemon();
|
bool try_connect_to_daemon();
|
||||||
bool ask_wallet_create_if_needed();
|
bool ask_wallet_create_if_needed();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Prints the seed with a nice message
|
* \brief Prints the seed with a nice message
|
||||||
* \param seed seed to print
|
* \param seed seed to print
|
||||||
|
@ -238,5 +240,6 @@ namespace cryptonote
|
||||||
std::thread m_auto_refresh_thread;
|
std::thread m_auto_refresh_thread;
|
||||||
std::mutex m_auto_refresh_mutex;
|
std::mutex m_auto_refresh_mutex;
|
||||||
std::condition_variable m_auto_refresh_cond;
|
std::condition_variable m_auto_refresh_cond;
|
||||||
|
std::atomic<bool> m_in_manual_refresh;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -680,6 +680,7 @@ void wallet2::refresh(uint64_t start_height, uint64_t & blocks_fetched, bool& re
|
||||||
get_short_chain_history(short_chain_history);
|
get_short_chain_history(short_chain_history);
|
||||||
pull_blocks(start_height, blocks_start_height, short_chain_history, blocks);
|
pull_blocks(start_height, blocks_start_height, short_chain_history, blocks);
|
||||||
|
|
||||||
|
m_run.store(true, std::memory_order_relaxed);
|
||||||
while(m_run.load(std::memory_order_relaxed))
|
while(m_run.load(std::memory_order_relaxed))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
Loading…
Reference in New Issue