aboutsummaryrefslogtreecommitdiff
path: root/src/server/worldserver
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2024-04-30 00:20:38 +0200
committerShauren <shauren.trinity@gmail.com>2024-04-30 00:20:38 +0200
commit8e3024a96ab06b5e2d6da529c5e3db9ce5744c4e (patch)
tree51f55eed5c2aa7e166a20732a771b739c82c73f8 /src/server/worldserver
parentcc9241784491198581a19f3f5502a42d048ea063 (diff)
Core/Misc: Refactor loading process to remove exit() calls that cause deadlocks because threads are terminated without proper cleanup
Diffstat (limited to 'src/server/worldserver')
-rw-r--r--src/server/worldserver/Main.cpp10
-rw-r--r--src/server/worldserver/TCSoap/TCSoap.cpp62
-rw-r--r--src/server/worldserver/TCSoap/TCSoap.h3
3 files changed, 45 insertions, 30 deletions
diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp
index 1aa1de63d02..f8eba01c60c 100644
--- a/src/server/worldserver/Main.cpp
+++ b/src/server/worldserver/Main.cpp
@@ -338,7 +338,8 @@ extern int main(int argc, char** argv)
// Initialize the World
sSecretMgr->Initialize(SECRET_OWNER_WORLDSERVER);
- sWorld->SetInitialWorldSettings();
+ if (!sWorld->SetInitialWorldSettings())
+ return 1;
auto mapManagementHandle = Trinity::make_unique_ptr_with_deleter(&dummy, [](void*)
{
@@ -359,7 +360,12 @@ extern int main(int argc, char** argv)
// Start soap serving thread if enabled
std::unique_ptr<std::thread, ShutdownTCSoapThread> soapThread;
if (sConfigMgr->GetBoolDefault("SOAP.Enabled", false))
- soapThread.reset(new std::thread(TCSoapThread, sConfigMgr->GetStringDefault("SOAP.IP", "127.0.0.1"), uint16(sConfigMgr->GetIntDefault("SOAP.Port", 7878))));
+ {
+ if (std::thread* soap = CreateSoapThread(sConfigMgr->GetStringDefault("SOAP.IP", "127.0.0.1"), uint16(sConfigMgr->GetIntDefault("SOAP.Port", 7878))))
+ soapThread.reset(soap);
+ else
+ return -1;
+ }
// Launch the worldserver listener socket
uint16 worldPort = uint16(sWorld->getIntConfig(CONFIG_PORT_WORLD));
diff --git a/src/server/worldserver/TCSoap/TCSoap.cpp b/src/server/worldserver/TCSoap/TCSoap.cpp
index 40955b21dbe..b367f502c90 100644
--- a/src/server/worldserver/TCSoap/TCSoap.cpp
+++ b/src/server/worldserver/TCSoap/TCSoap.cpp
@@ -16,49 +16,57 @@
*/
#include "TCSoap.h"
-#include "soapH.h"
-#include "soapStub.h"
-#include "Realm.h"
-#include "World.h"
#include "AccountMgr.h"
+#include "IpAddress.h"
#include "Log.h"
+#include "Memory.h"
+#include "Realm.h"
+#include "World.h"
+#include "soapH.h"
+#include "soapStub.h"
-void TCSoapThread(const std::string& host, uint16 port)
+std::thread* CreateSoapThread(const std::string& host, uint16 port)
{
- struct soap soap;
- soap_init(&soap);
- soap_set_imode(&soap, SOAP_C_UTFSTRING);
- soap_set_omode(&soap, SOAP_C_UTFSTRING);
+ auto soap = Trinity::make_unique_ptr_with_deleter<struct soap*>(new struct soap(), [](struct soap* soap)
+ {
+ soap_destroy(soap);
+ soap_end(soap);
+ soap_done(soap);
+ delete soap;
+ });
+
+ soap_init(soap.get());
+ soap_set_imode(soap.get(), SOAP_C_UTFSTRING);
+ soap_set_omode(soap.get(), SOAP_C_UTFSTRING);
#if TRINITY_PLATFORM != TRINITY_PLATFORM_WINDOWS
- soap.bind_flags = SO_REUSEADDR;
+ soap->bind_flags = SO_REUSEADDR;
#endif
// check every 3 seconds if world ended
- soap.accept_timeout = 3;
- soap.recv_timeout = 5;
- soap.send_timeout = 5;
- if (!soap_valid_socket(soap_bind(&soap, host.c_str(), port, 100)))
+ soap->accept_timeout = 3;
+ soap->recv_timeout = 5;
+ soap->send_timeout = 5;
+ if (!soap_valid_socket(soap_bind(soap.get(), host.c_str(), port, 100)))
{
TC_LOG_ERROR("network.soap", "Couldn't bind to {}:{}", host, port);
- exit(-1);
+ return nullptr;
}
TC_LOG_INFO("network.soap", "Bound to http://{}:{}", host, port);
- while (!World::IsStopped())
+ return new std::thread([soap = std::move(soap)]
{
- if (!soap_valid_socket(soap_accept(&soap)))
- continue; // ran into an accept timeout
-
- TC_LOG_DEBUG("network.soap", "Accepted connection from IP={}.{}.{}.{}", (int)(soap.ip>>24)&0xFF, (int)(soap.ip>>16)&0xFF, (int)(soap.ip>>8)&0xFF, (int)soap.ip&0xFF);
- struct soap* thread_soap = soap_copy(&soap);// make a safe copy
- process_message(thread_soap);
- }
-
- soap_destroy(&soap);
- soap_end(&soap);
- soap_done(&soap);
+ while (!World::IsStopped())
+ {
+ if (!soap_valid_socket(soap_accept(soap.get())))
+ continue; // ran into an accept timeout
+
+ struct soap* thread_soap = soap_copy(soap.get());// make a safe copy
+ TC_LOG_DEBUG("network.soap", "Accepted connection from IP={}", Trinity::Net::make_address_v4(thread_soap->ip).to_string());
+ process_message(thread_soap);
+ }
+ });
}
void process_message(struct soap* soap_message)
diff --git a/src/server/worldserver/TCSoap/TCSoap.h b/src/server/worldserver/TCSoap/TCSoap.h
index b8be9ba4cd8..eec463836be 100644
--- a/src/server/worldserver/TCSoap/TCSoap.h
+++ b/src/server/worldserver/TCSoap/TCSoap.h
@@ -21,9 +21,10 @@
#include "Define.h"
#include <future>
#include <string>
+#include <thread>
void process_message(struct soap* soap_message);
-void TCSoapThread(const std::string& host, uint16 port);
+std::thread* CreateSoapThread(const std::string& host, uint16 port);
class SOAPCommand
{