forked from lthn/blockchain
Merge branch 'develop' into tor
This commit is contained in:
commit
7790da8fe1
8 changed files with 251 additions and 20 deletions
153
src/common/threads_pool.h
Normal file
153
src/common/threads_pool.h
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
// Copyright (c) 2014-2019 Zano Project
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thread>
|
||||
#include <string>
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
|
||||
struct call_executor_base
|
||||
{
|
||||
virtual void execute() = 0;
|
||||
};
|
||||
|
||||
template<typename t_executor_func>
|
||||
struct call_executor_t : public call_executor_base
|
||||
{
|
||||
call_executor_t(t_executor_func f) :m_func(f)
|
||||
{}
|
||||
t_executor_func m_func;
|
||||
virtual void execute()
|
||||
{
|
||||
m_func();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename t_executor_func>
|
||||
std::shared_ptr<call_executor_base> build_call_executor(t_executor_func func)
|
||||
{
|
||||
std::shared_ptr<call_executor_base> res(static_cast<call_executor_base*>(new call_executor_t<t_executor_func>(func)));
|
||||
return res;
|
||||
}
|
||||
|
||||
class threads_pool
|
||||
{
|
||||
public:
|
||||
typedef std::list<std::shared_ptr<call_executor_base>> jobs_container;
|
||||
|
||||
template<typename t_executor_func>
|
||||
static void add_job_to_container(jobs_container& cntr, t_executor_func func)
|
||||
{
|
||||
cntr.push_back(std::shared_ptr<call_executor_base>(static_cast<call_executor_base*>(new call_executor_t<t_executor_func>(func))));
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
int num_threads = std::thread::hardware_concurrency();
|
||||
this->init(num_threads);
|
||||
}
|
||||
void init(unsigned int num_threads)
|
||||
{
|
||||
m_is_stop = false;
|
||||
|
||||
for (int i = 0; i < num_threads; i++)
|
||||
{
|
||||
m_threads.push_back(std::thread([this]() {this->worker_func(); }));
|
||||
}
|
||||
}
|
||||
|
||||
threads_pool() : m_is_stop(false), m_threads_counter(0)
|
||||
{}
|
||||
|
||||
template<typename t_executor_func>
|
||||
bool add_job(t_executor_func func)
|
||||
{
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_queue_mutex);
|
||||
m_jobs_que.push_back(build_call_executor(func));
|
||||
}
|
||||
m_condition.notify_one();
|
||||
return true;
|
||||
}
|
||||
|
||||
void add_batch_and_wait(const jobs_container& cntr)
|
||||
{
|
||||
std::condition_variable batch_condition;
|
||||
std::mutex batch_mutex;
|
||||
|
||||
|
||||
std::atomic<size_t> cnt = 0;
|
||||
for (const auto& jb : cntr)
|
||||
{
|
||||
call_executor_base* pjob = jb.get();
|
||||
add_job([&, pjob]() {
|
||||
pjob->execute();
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(batch_mutex);
|
||||
cnt++;
|
||||
}
|
||||
batch_condition.notify_one();
|
||||
});
|
||||
}
|
||||
|
||||
std::unique_lock<std::mutex> lock(batch_mutex);
|
||||
batch_condition.wait(lock, [&]()
|
||||
{
|
||||
return cnt == cntr.size();
|
||||
});
|
||||
LOG_PRINT_L0("All jobs finiahed");
|
||||
}
|
||||
|
||||
~threads_pool()
|
||||
{
|
||||
m_is_stop = true;
|
||||
m_condition.notify_all();
|
||||
for (auto& th : m_threads)
|
||||
{
|
||||
th.join();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void worker_func()
|
||||
{
|
||||
LOG_PRINT_L0("Worker thread is started");
|
||||
while (true)
|
||||
{
|
||||
std::shared_ptr<call_executor_base> job;
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_queue_mutex);
|
||||
|
||||
m_condition.wait(lock, [this]()
|
||||
{
|
||||
return !m_jobs_que.empty() || m_is_stop;
|
||||
});
|
||||
if (m_is_stop)
|
||||
{
|
||||
LOG_PRINT_L0("Worker thread is finished");
|
||||
return;
|
||||
}
|
||||
|
||||
job = m_jobs_que.front();
|
||||
m_jobs_que.pop_front();
|
||||
}
|
||||
|
||||
job->execute();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
jobs_container m_jobs_que;
|
||||
std::condition_variable m_condition;
|
||||
std::mutex m_queue_mutex;
|
||||
std::vector<std::thread> m_threads;
|
||||
std::atomic<bool> m_is_stop;
|
||||
std::atomic<int64_t> m_threads_counter;
|
||||
};
|
||||
}
|
||||
|
|
@ -744,11 +744,25 @@ void qt_log_message_handler(QtMsgType type, const QMessageLogContext &context, c
|
|||
}
|
||||
}
|
||||
|
||||
bool MainWindow::remove_ipc()
|
||||
{
|
||||
try {
|
||||
boost::interprocess::message_queue::remove(GUI_IPC_MESSAGE_CHANNEL_NAME);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool MainWindow::init_ipc_server()
|
||||
{
|
||||
|
||||
//in case previous instance wasn't close graceful, ipc channel will remain open and new creation will fail, so we
|
||||
//trying to close it anyway before open, to make sure there are no dead channels. If there are another running instance, it wom't
|
||||
//let channel to close, so it will fail later on creating channel
|
||||
remove_ipc();
|
||||
#define GUI_IPC_BUFFER_SIZE 10000
|
||||
try {
|
||||
//Create a message queue.
|
||||
|
|
@ -772,21 +786,23 @@ bool MainWindow::init_ipc_server()
|
|||
bool data_received = pmq->timed_receive((void*)buff.data(), GUI_IPC_BUFFER_SIZE, recvd_size, priority, boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) + boost::posix_time::milliseconds(1000));
|
||||
if (data_received && recvd_size != 0)
|
||||
{
|
||||
buff.resize(recvd_size, '*');
|
||||
handle_ipc_event(buff);//todo process token
|
||||
}
|
||||
}
|
||||
boost::interprocess::message_queue::remove(GUI_IPC_MESSAGE_CHANNEL_NAME);
|
||||
remove_ipc();
|
||||
LOG_PRINT_L0("IPC Handling thread finished");
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
remove_ipc();
|
||||
boost::interprocess::message_queue::remove(GUI_IPC_MESSAGE_CHANNEL_NAME);
|
||||
LOG_ERROR("Failed to receive IPC que: " << ex.what());
|
||||
}
|
||||
|
||||
catch (...)
|
||||
{
|
||||
boost::interprocess::message_queue::remove(GUI_IPC_MESSAGE_CHANNEL_NAME);
|
||||
remove_ipc();
|
||||
LOG_ERROR("Failed to receive IPC que: unknown exception");
|
||||
}
|
||||
});
|
||||
|
|
@ -810,8 +826,8 @@ bool MainWindow::init_ipc_server()
|
|||
|
||||
bool MainWindow::handle_ipc_event(const std::string& arguments)
|
||||
{
|
||||
std::string zzz = "Received IPC: " + arguments;
|
||||
message_box(zzz.c_str());
|
||||
std::string zzz = std::string("Received IPC: ") + arguments.c_str();
|
||||
std::cout << zzz;//message_box(zzz.c_str());
|
||||
|
||||
handle_deeplink_click(arguments.c_str());
|
||||
|
||||
|
|
|
|||
|
|
@ -240,6 +240,7 @@ private:
|
|||
bool load_app_config();
|
||||
bool init_window();
|
||||
bool init_ipc_server();
|
||||
bool remove_ipc();
|
||||
|
||||
|
||||
std::string get_wallet_log_prefix(size_t wallet_id) const { return m_backend.get_wallet_log_prefix(wallet_id); }
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 02e277cbda5c9b40f8bb445fb2f6b87a3a780431
|
||||
Subproject commit 22bed634e5f3c1da0b4d4b1262d57a2445dba08b
|
||||
|
|
@ -23,6 +23,8 @@
|
|||
#include "print_struct_to_json.h"
|
||||
#include "free_space_check.h"
|
||||
#include "htlc_hash_tests.h"
|
||||
#include "threads_pool_tests.h"
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
|
|
@ -33,21 +35,23 @@ int main(int argc, char** argv)
|
|||
epee::log_space::log_singletone::get_default_log_file().c_str(),
|
||||
epee::log_space::log_singletone::get_default_log_folder().c_str());
|
||||
|
||||
|
||||
std::string buf1 = tools::get_varint_data<uint64_t>(CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX);
|
||||
std::string buf2 = tools::get_varint_data<uint64_t>(CURRENCY_PUBLIC_INTEG_ADDRESS_BASE58_PREFIX);
|
||||
std::string buf3 = tools::get_varint_data<uint64_t>(CURRENCY_PUBLIC_INTEG_ADDRESS_V2_BASE58_PREFIX);
|
||||
std::string buf4 = tools::get_varint_data<uint64_t>(CURRENCY_PUBLIC_AUDITABLE_ADDRESS_BASE58_PREFIX);
|
||||
std::string buf5 = tools::get_varint_data<uint64_t>(CURRENCY_PUBLIC_AUDITABLE_INTEG_ADDRESS_BASE58_PREFIX);
|
||||
|
||||
std::cout << "Buf1: " << epee::string_tools::buff_to_hex_nodelimer(buf1) << ENDL;
|
||||
std::cout << "Buf2: " << epee::string_tools::buff_to_hex_nodelimer(buf2) << ENDL;
|
||||
std::cout << "Buf3: " << epee::string_tools::buff_to_hex_nodelimer(buf3) << ENDL;
|
||||
std::cout << "Buf4: " << epee::string_tools::buff_to_hex_nodelimer(buf4) << ENDL;
|
||||
std::cout << "Buf5: " << epee::string_tools::buff_to_hex_nodelimer(buf5) << ENDL;
|
||||
thread_pool_tests();
|
||||
|
||||
|
||||
do_htlc_hash_tests();
|
||||
// std::string buf1 = tools::get_varint_data<uint64_t>(CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX);
|
||||
// std::string buf2 = tools::get_varint_data<uint64_t>(CURRENCY_PUBLIC_INTEG_ADDRESS_BASE58_PREFIX);
|
||||
// std::string buf3 = tools::get_varint_data<uint64_t>(CURRENCY_PUBLIC_INTEG_ADDRESS_V2_BASE58_PREFIX);
|
||||
// std::string buf4 = tools::get_varint_data<uint64_t>(CURRENCY_PUBLIC_AUDITABLE_ADDRESS_BASE58_PREFIX);
|
||||
// std::string buf5 = tools::get_varint_data<uint64_t>(CURRENCY_PUBLIC_AUDITABLE_INTEG_ADDRESS_BASE58_PREFIX);
|
||||
//
|
||||
// std::cout << "Buf1: " << epee::string_tools::buff_to_hex_nodelimer(buf1) << ENDL;
|
||||
// std::cout << "Buf2: " << epee::string_tools::buff_to_hex_nodelimer(buf2) << ENDL;
|
||||
// std::cout << "Buf3: " << epee::string_tools::buff_to_hex_nodelimer(buf3) << ENDL;
|
||||
// std::cout << "Buf4: " << epee::string_tools::buff_to_hex_nodelimer(buf4) << ENDL;
|
||||
// std::cout << "Buf5: " << epee::string_tools::buff_to_hex_nodelimer(buf5) << ENDL;
|
||||
//
|
||||
//
|
||||
//do_htlc_hash_tests();
|
||||
//run_serialization_performance_test();
|
||||
//return 1;
|
||||
//run_core_market_performance_tests(100000);
|
||||
|
|
|
|||
57
tests/performance_tests/threads_pool_tests.h
Normal file
57
tests/performance_tests/threads_pool_tests.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
// Copyright (c) 2019 The Zano developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "include_base_utils.h"
|
||||
#include "common/threads_pool.h"
|
||||
|
||||
|
||||
inline
|
||||
void thread_pool_tests_simple()
|
||||
{
|
||||
{
|
||||
utils::threads_pool pool;
|
||||
pool.init();
|
||||
std::atomic<uint64_t> count_jobs_finished = 0;
|
||||
size_t i = 0;
|
||||
for (; i != 10; i++)
|
||||
{
|
||||
pool.add_job([&, i]() {LOG_PRINT_L0("Job " << i << " started"); epee::misc_utils::sleep_no_w(10000); ++count_jobs_finished; LOG_PRINT_L0("Job " << i << " finished"); });
|
||||
}
|
||||
while (count_jobs_finished != i)
|
||||
{
|
||||
epee::misc_utils::sleep_no_w(500);
|
||||
}
|
||||
LOG_PRINT_L0("All jobs finished");
|
||||
}
|
||||
LOG_PRINT_L0("Scope left");
|
||||
}
|
||||
|
||||
inline
|
||||
void thread_pool_tests()
|
||||
{
|
||||
{
|
||||
utils::threads_pool pool;
|
||||
pool.init();
|
||||
std::atomic<uint64_t> count_jobs_finished = 0;
|
||||
|
||||
utils::threads_pool::jobs_container jobs;
|
||||
size_t i = 0;
|
||||
for (; i != 10; i++)
|
||||
{
|
||||
utils::threads_pool::add_job_to_container(jobs, [&, i]() {LOG_PRINT_L0("Job " << i << " started"); epee::misc_utils::sleep_no_w(10000); ++count_jobs_finished; LOG_PRINT_L0("Job " << i << " finished"); });
|
||||
}
|
||||
|
||||
pool.add_batch_and_wait(jobs);
|
||||
if (count_jobs_finished != i)
|
||||
{
|
||||
LOG_ERROR("Test failed");
|
||||
return;
|
||||
}
|
||||
LOG_PRINT_L0("All jobs finished");
|
||||
}
|
||||
LOG_PRINT_L0("Scope left");
|
||||
}
|
||||
|
|
@ -29,7 +29,7 @@ create_desktop_icon()
|
|||
echo GenericName=Zano | tee -a $target_file_name > /dev/null
|
||||
echo Comment=Privacy blockchain | tee -a $target_file_name > /dev/null
|
||||
echo Icon=$script_dir/html/files/desktop_linux_icon.png | tee -a $target_file_name > /dev/null
|
||||
echo Exec=$script_dir/Zano.sh %u | tee -a $target_file_name > /dev/null
|
||||
echo Exec=$script_dir/Zano.sh --deeplink-params=%u | tee -a $target_file_name > /dev/null
|
||||
echo Terminal=true | tee -a $target_file_name > /dev/null
|
||||
echo Type=Application | tee -a $target_file_name > /dev/null
|
||||
echo "Categories=Qt;Utility;" | tee -a $target_file_name > /dev/null
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ Root: HKCR; Subkey: "ZanoWalletDataFile\DefaultIcon"; ValueType: string; ValueNa
|
|||
Root: HKCR; Subkey: "ZanoWalletDataKyesFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\Zano.exe,0"
|
||||
|
||||
Root: HKCR; Subkey: "Zano"; ValueType: string; ValueName: "URL Protocol"; ValueData: ""
|
||||
Root: HKCR; Subkey: "Zano\shell\open\command"; ValueType: string; ValueName: ""; ValueData: "{app}\Zano.exe %1"
|
||||
Root: HKCR; Subkey: "Zano\shell\open\command"; ValueType: string; ValueName: ""; ValueData: "{app}\Zano.exe --deeplink-params=%1"
|
||||
|
||||
|
||||
[Files]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue