forked from lthn/blockchain
fixed ancient p2p bug
This commit is contained in:
parent
a13eedf556
commit
09ddda7dba
4 changed files with 60 additions and 7 deletions
|
|
@ -44,6 +44,18 @@ namespace net_utils {
|
|||
/************************************************************************/
|
||||
DISABLE_VS_WARNINGS(4355)
|
||||
|
||||
|
||||
|
||||
template <typename, typename = std::void_t<>>
|
||||
struct has_pre_destructor_handler : std::false_type {};
|
||||
|
||||
// This specialization is selected if T has a valid 'b()' that can be called
|
||||
template <typename T>
|
||||
struct has_pre_destructor_handler<T, std::void_t<decltype(std::declval<T&>().on_pre_destroy())>>
|
||||
: std::true_type {};
|
||||
|
||||
|
||||
|
||||
template<class t_protocol_handler>
|
||||
connection<t_protocol_handler>::connection(boost::asio::io_service& io_service,
|
||||
typename t_protocol_handler::config_type& config, volatile uint32_t& sock_count, i_connection_filter*& pfilter)
|
||||
|
|
@ -66,6 +78,12 @@ connection<t_protocol_handler>::~connection()
|
|||
{
|
||||
NESTED_TRY_ENTRY();
|
||||
|
||||
if constexpr (has_pre_destructor_handler<t_protocol_handler>::value)
|
||||
{
|
||||
m_protocol_handler.on_pre_destroy();
|
||||
}
|
||||
|
||||
|
||||
if(!m_was_shutdown) {
|
||||
LOG_PRINT_L3("[sock " << socket_.native_handle() << "] Socket destroyed without shutdown.");
|
||||
shutdown();
|
||||
|
|
|
|||
|
|
@ -252,6 +252,7 @@ public:
|
|||
LOG_PRINT_CC(m_connection_context, "[LEVIN_PROTOCOL" << this << "] CONSTRUCTED", LOG_LEVEL_4);
|
||||
}
|
||||
|
||||
|
||||
virtual ~async_protocol_handler()
|
||||
{
|
||||
NESTED_TRY_ENTRY();
|
||||
|
|
@ -278,6 +279,11 @@ public:
|
|||
NESTED_CATCH_ENTRY(__func__);
|
||||
}
|
||||
|
||||
void on_pre_destroy()
|
||||
{
|
||||
m_config.del_connection(this);
|
||||
}
|
||||
|
||||
bool start_outer_call()
|
||||
{
|
||||
LOG_PRINT_CC_L4(m_connection_context, "[LEVIN_PROTOCOL" << this << "] -->> start_outer_call");
|
||||
|
|
|
|||
|
|
@ -277,7 +277,7 @@ namespace epee
|
|||
|
||||
#define POTENTIAL_HANG_PREVENT_LIMIT 1000
|
||||
|
||||
|
||||
#define DEADLOCK_GUARD_JOURNAL_LIMIT 1000
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
|
|
@ -290,11 +290,11 @@ namespace epee
|
|||
struct thread_info
|
||||
{
|
||||
std::map<lock_reference_type, size_t> m_owned_objects;
|
||||
bool is_blocked;
|
||||
lock_reference_type blocker_lock;
|
||||
const char* block_location;
|
||||
const char* func_name;
|
||||
const char* lock_name;
|
||||
bool is_blocked = false;
|
||||
lock_reference_type blocker_lock = nullptr;
|
||||
const char* block_location = "unknown";
|
||||
const char* func_name = "unknown";
|
||||
const char* lock_name = "unknown";
|
||||
std::string thread_name;
|
||||
};
|
||||
|
||||
|
|
@ -307,6 +307,18 @@ namespace epee
|
|||
std::map<lock_reference_type, thread_id_to_info_map::iterator> m_owned_locks_to_thread;
|
||||
// deadlock journal
|
||||
std::list<std::string> m_deadlock_journal;
|
||||
//lock/unlock journal
|
||||
struct journal_entry
|
||||
{
|
||||
std::thread::id tid;
|
||||
lock_reference_type lock = nullptr;
|
||||
bool is_lock_event = false;
|
||||
const char* func_name = "unkonwn";
|
||||
const char* lock_name = "unkonwn";
|
||||
std::string thread_name;
|
||||
};
|
||||
|
||||
std::list<journal_entry> m_journal;
|
||||
|
||||
public:
|
||||
void on_before_lock(lock_reference_type lock, const char* func_name, const char* loction, const char* lock_name, const std::string& thread_name)
|
||||
|
|
@ -363,6 +375,10 @@ namespace epee
|
|||
}
|
||||
else
|
||||
{
|
||||
m_journal.push_front(journal_entry{ this_id, lock, false, "", "", ""});
|
||||
if (m_journal.size() > DEADLOCK_GUARD_JOURNAL_LIMIT)
|
||||
m_journal.pop_back();
|
||||
|
||||
m_owned_locks_to_thread.erase(lock_to_thread_it);
|
||||
}
|
||||
it->second.m_owned_objects.erase(ownership_it);
|
||||
|
|
@ -400,6 +416,15 @@ namespace epee
|
|||
ss << "-----------------------------------------------------------------------" << std::endl << err << std::endl;
|
||||
}
|
||||
|
||||
ss << "Ownership history history:" << std::endl;
|
||||
size_t count = 0;
|
||||
for (auto entry : m_journal)
|
||||
{
|
||||
ss << "tid(" << entry.thread_name << "): " << entry.tid << ", lock_addr: " << entry.lock << (entry.is_lock_event ? "-->":"<--") << ", func: " << (entry.func_name ? entry.func_name:"") << ", lock_name: " << (entry.lock_name ? entry.lock_name : "") << std::endl;
|
||||
if (++count > 100)
|
||||
break;
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
|
@ -429,6 +454,10 @@ namespace epee
|
|||
//need to add lock-to-thread reccord
|
||||
m_owned_locks_to_thread[lock] = it;
|
||||
DO_DEBUG_COUT("[" << std::this_thread::get_id() << "][ADDED_OWNERSHIP]: " << lock << std::endl);
|
||||
m_journal.push_front(journal_entry{ this_id, lock, true, it->second.func_name, it->second.lock_name, it->second.thread_name });
|
||||
if (m_journal.size() > DEADLOCK_GUARD_JOURNAL_LIMIT)
|
||||
m_journal.pop_back();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ namespace tools
|
|||
}
|
||||
|
||||
// okay, let's download
|
||||
|
||||
LOG_PRINT_MAGENTA("Pre-download required: local db size: " << sz << ", pre_download.unpacked_size = " << pre_download.unpacked_size << ", flag_force_predownload: " << (flag_force_predownload ? "true":"false"), LOG_LEVEL_0);
|
||||
std::string downloading_file_path = db_main_file_path + ".download";
|
||||
if (!command_line::has_arg(vm, command_line::arg_process_predownload_from_path))
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue