[BitMessage] Shutdown workaround

This starts a thread in the game's shutdown routine
and destroys BitMRC in a separate thread to prevent deadlocks.
This is not a good fix
This commit is contained in:
momo5502 2016-11-12 12:55:20 +01:00
parent 72c19cb968
commit ea3660bbf8
2 changed files with 59 additions and 14 deletions

View File

@ -8,6 +8,7 @@ using namespace Utils;
namespace Components namespace Components
{ {
std::thread BitMessage::ShutDownThread;
BitMRC* BitMessage::BMClient; BitMRC* BitMessage::BMClient;
BitMessage::BitMessage() BitMessage::BitMessage()
@ -16,6 +17,15 @@ namespace Components
Logger::Print("Initializing BitMessage...\n"); Logger::Print("Initializing BitMessage...\n");
#endif // DEBUG #endif // DEBUG
QuickPatch::OnShutdown([] ()
{
BitMessage::ShutDownThread = std::thread(BitMessage::ShutDown);
if (BitMessage::ShutDownThread.joinable())
{
BitMessage::ShutDownThread.join();
}
});
BitMessage::BMClient = new BitMRC(BITMESSAGE_OBJECT_STORAGE_FILENAME, BITMESSAGE_KEYS_FILENAME); BitMessage::BMClient = new BitMRC(BITMESSAGE_OBJECT_STORAGE_FILENAME, BITMESSAGE_KEYS_FILENAME);
BitMessage::BMClient->init(); BitMessage::BMClient->init();
BitMessage::BMClient->defaultTTL = 1 * 60 * 60; // 1 hour BitMessage::BMClient->defaultTTL = 1 * 60 * 60; // 1 hour
@ -34,7 +44,7 @@ namespace Components
BitMessage::BMClient->start(); BitMessage::BMClient->start();
#ifdef DEBUG #ifdef DEBUG
Command::Add("bm_send", [](Command::Params params) Command::Add("bm_send", [] (Command::Params params)
{ {
if (params.Length() < 3) return; if (params.Length() < 3) return;
@ -57,7 +67,7 @@ namespace Components
} }
}); });
Command::Add("bm_sendb", [](Command::Params params) Command::Add("bm_sendb", [] (Command::Params params)
{ {
if (params.Length() < 2) return; if (params.Length() < 2) return;
@ -68,8 +78,10 @@ namespace Components
Logger::Print("Broadcast done.\n"); Logger::Print("Broadcast done.\n");
}); });
Command::Add("bm_check_messages", [](Command::Params) Command::Add("bm_check_messages", [] (Command::Params)
{ {
if (!BitMessage::BMClient) return;
while (BitMessage::BMClient->new_messages.size() > 0) while (BitMessage::BMClient->new_messages.size() > 0)
{ {
auto msg = BitMessage::BMClient->new_messages.pop(); auto msg = BitMessage::BMClient->new_messages.pop();
@ -77,13 +89,15 @@ namespace Components
} }
}); });
Command::Add("bm_check_connections", [](Command::Params) Command::Add("bm_check_connections", [] (Command::Params)
{ {
if (!BitMessage::BMClient) return;
std::shared_lock<std::shared_timed_mutex> mlock(BitMessage::BMClient->mutex_nodes); std::shared_lock<std::shared_timed_mutex> mlock(BitMessage::BMClient->mutex_nodes);
for (auto& node : BitMessage::BMClient->Nodes) for (auto& node : BitMessage::BMClient->Nodes)
{ {
switch (node->state) { switch (node->state)
{
case 0: // Not connected case 0: // Not connected
Logger::Print("%s: Disconnected\n", node->Ip.data()); Logger::Print("%s: Disconnected\n", node->Ip.data());
break; break;
@ -102,8 +116,9 @@ namespace Components
mlock.unlock(); mlock.unlock();
}); });
Command::Add("bm_check_privatekey", [](Command::Params) Command::Add("bm_check_privatekey", [] (Command::Params)
{ {
if (!BitMessage::BMClient) return;
std::shared_lock<std::shared_timed_mutex> mlock(BitMessage::BMClient->mutex_priv); std::shared_lock<std::shared_timed_mutex> mlock(BitMessage::BMClient->mutex_priv);
if (BitMessage::BMClient->PrivAddresses.empty()) if (BitMessage::BMClient->PrivAddresses.empty())
@ -121,8 +136,9 @@ namespace Components
mlock.unlock(); mlock.unlock();
}); });
Command::Add("bm_check_publickey", [](Command::Params) Command::Add("bm_check_publickey", [] (Command::Params)
{ {
if (!BitMessage::BMClient) return;
std::shared_lock<std::shared_timed_mutex> mlock(BitMessage::BMClient->mutex_pub); std::shared_lock<std::shared_timed_mutex> mlock(BitMessage::BMClient->mutex_pub);
if (BitMessage::BMClient->PubAddresses.empty()) if (BitMessage::BMClient->PubAddresses.empty())
@ -138,13 +154,14 @@ namespace Components
mlock.unlock(); mlock.unlock();
}); });
Command::Add("bm_save", [](Command::Params) Command::Add("bm_save", [] (Command::Params)
{ {
BitMessage::Save(); BitMessage::Save();
}); });
Command::Add("bm_address_public", [](Command::Params params) Command::Add("bm_address_public", [] (Command::Params params)
{ {
if (!BitMessage::BMClient) return;
if (params.Length() < 2) return; if (params.Length() < 2) return;
ustring addre; ustring addre;
@ -163,8 +180,9 @@ namespace Components
} }
}); });
Command::Add("bm_address_broadcast", [](Command::Params params) Command::Add("bm_address_broadcast", [] (Command::Params params)
{ {
if (!BitMessage::BMClient) return;
if (params.Length() < 2) return; if (params.Length() < 2) return;
ustring addre; ustring addre;
@ -183,22 +201,31 @@ namespace Components
#endif #endif
} }
BitMessage::~BitMessage() void BitMessage::ShutDown()
{ {
BitMessage::Save(); BitMessage::Save();
delete BitMessage::BMClient; delete BitMessage::BMClient;
BitMessage::BMClient = nullptr; BitMessage::BMClient = nullptr;
} }
BitMessage::~BitMessage()
{
if (BitMessage::BMClient)
{
BitMessage::ShutDown();
}
}
void BitMessage::SetDefaultTTL(time_t ttl) void BitMessage::SetDefaultTTL(time_t ttl)
{ {
if (!BitMessage::BMClient) return;
BitMessage::BMClient->defaultTTL = ttl; BitMessage::BMClient->defaultTTL = ttl;
} }
bool BitMessage::RequestPublicKey(std::string targetAddress) bool BitMessage::RequestPublicKey(std::string targetAddress)
{ {
if (!BitMessage::BMClient) return false;
// Convert to ustring // Convert to ustring
ustring targetAddressU; ustring targetAddressU;
targetAddressU.fromString(targetAddress); targetAddressU.fromString(targetAddress);
@ -217,6 +244,7 @@ namespace Components
PubAddr* BitMessage::FindPublicKey(PubAddr address) PubAddr* BitMessage::FindPublicKey(PubAddr address)
{ {
if (!BitMessage::BMClient) return nullptr;
std::shared_lock<std::shared_timed_mutex> mlock(BitMessage::BMClient->mutex_pub); std::shared_lock<std::shared_timed_mutex> mlock(BitMessage::BMClient->mutex_pub);
PubAddr* retval = nullptr; PubAddr* retval = nullptr;
@ -240,6 +268,8 @@ namespace Components
bool BitMessage::WaitForPublicKey(std::string targetAddress) bool BitMessage::WaitForPublicKey(std::string targetAddress)
{ {
if (!BitMessage::BMClient) return false;
// Convert to ustring // Convert to ustring
ustring targetAddressU; ustring targetAddressU;
targetAddressU.fromString(targetAddress); targetAddressU.fromString(targetAddress);
@ -280,6 +310,8 @@ namespace Components
bool BitMessage::Subscribe(std::string targetAddress) bool BitMessage::Subscribe(std::string targetAddress)
{ {
if (!BitMessage::BMClient) return false;
// Convert to ustring // Convert to ustring
ustring targetAddressU; ustring targetAddressU;
targetAddressU.fromString(targetAddress); targetAddressU.fromString(targetAddress);
@ -298,6 +330,8 @@ namespace Components
bool BitMessage::SendMsg(std::string targetAddress, std::string message, time_t ttl) bool BitMessage::SendMsg(std::string targetAddress, std::string message, time_t ttl)
{ {
if (!BitMessage::BMClient) return false;
// Convert target address to ustring // Convert target address to ustring
ustring targetAddressU; ustring targetAddressU;
targetAddressU.fromString(targetAddress); targetAddressU.fromString(targetAddress);
@ -329,6 +363,8 @@ namespace Components
bool BitMessage::SendBroadcast(std::string message, time_t ttl) bool BitMessage::SendBroadcast(std::string message, time_t ttl)
{ {
if (!BitMessage::BMClient) return false;
// Convert message to ustring // Convert message to ustring
ustring messageU; ustring messageU;
messageU.fromString(message); messageU.fromString(message);
@ -348,6 +384,8 @@ namespace Components
bool BitMessage::InitAddr() bool BitMessage::InitAddr()
{ {
if (!BitMessage::BMClient) return false;
#ifdef DEBUG #ifdef DEBUG
Logger::Print("Generating BM address...\n"); Logger::Print("Generating BM address...\n");
#endif #endif
@ -363,7 +401,10 @@ namespace Components
void BitMessage::Save() void BitMessage::Save()
{ {
BitMessage::BMClient->save(); if (BitMessage::BMClient)
{
BitMessage::BMClient->save();
}
} }
} }

View File

@ -28,8 +28,12 @@ namespace Components
static BitMRC* BMClient; static BitMRC* BMClient;
private: private:
static std::thread ShutDownThread;
static PubAddr* FindPublicKey(PubAddr addr); static PubAddr* FindPublicKey(PubAddr addr);
static bool InitAddr(); static bool InitAddr();
static void ShutDown();
}; };
} }