fix exit crash bug
This commit is contained in:
+52
-12
@@ -12,9 +12,10 @@ class ServerCore::Impl
|
||||
{
|
||||
public:
|
||||
int port = 0;
|
||||
webcc::Server* ccServer = nullptr;
|
||||
std::thread thServer;
|
||||
IPTable BlockedIPs;
|
||||
std::thread thServer;
|
||||
webcc::Server* ccServer = nullptr;
|
||||
std::atomic_bool server_started = false;
|
||||
|
||||
public:
|
||||
explicit Impl(int port)
|
||||
@@ -30,19 +31,28 @@ public:
|
||||
{
|
||||
if(ccServer != nullptr)
|
||||
{
|
||||
if(ccServer->IsRunning())
|
||||
ccServer->Stop();
|
||||
// if(ccServer->IsRunning())
|
||||
// ccServer->Stop();
|
||||
// delete ccServer;
|
||||
//Fix Crash
|
||||
ccServer->Stop();
|
||||
if (thServer.joinable())
|
||||
thServer.join();
|
||||
|
||||
delete ccServer;
|
||||
ccServer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
static void ServerThreadFunction(webcc::Server* server, int worker_thread, int loop_thread)
|
||||
static void ServerThreadFunction(webcc::Server* server, int worker_thread, int loop_thread, std::atomic_bool* started_flag)
|
||||
{
|
||||
if (server == nullptr)
|
||||
return;
|
||||
server->set_buffer_size(65535);
|
||||
SCLOGF_INFO("ServerCore thread ready: {} Worker(s), {} Loop(s)", worker_thread, loop_thread);
|
||||
if (started_flag)
|
||||
started_flag->store(true, std::memory_order_release);
|
||||
server->Run(worker_thread, loop_thread);
|
||||
return;
|
||||
}
|
||||
@@ -88,17 +98,45 @@ void ServerCore::Run(int worker_thread, int loop_thread)
|
||||
return;
|
||||
}
|
||||
|
||||
void ServerCore::ThreadRun(int worker_thread, int loop_thread)
|
||||
bool ServerCore::ThreadRun(int worker_thread, int loop_thread)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
if (pimpl->ccServer == nullptr)
|
||||
return;
|
||||
pimpl->thServer = std::thread(Impl::ServerThreadFunction, pimpl->ccServer, worker_thread, loop_thread);
|
||||
pimpl->thServer.detach();
|
||||
std::this_thread::sleep_for(100ms);
|
||||
if (pimpl->ccServer->IsRunning())
|
||||
return false;
|
||||
if (pimpl->thServer.joinable())
|
||||
{
|
||||
SCLOG_ERROR("ServerCore::ThreadRun called while a server thread is already active");
|
||||
return false; // 或直接 return,视你采纳下面的返回值方案而定
|
||||
}
|
||||
pimpl->server_started.store(false, std::memory_order_relaxed);
|
||||
pimpl->thServer = std::thread(Impl::ServerThreadFunction, pimpl->ccServer, worker_thread, loop_thread, &pimpl->server_started);
|
||||
bool reached_run = false;
|
||||
for (int i = 0; i < 500; i++)
|
||||
{
|
||||
if (pimpl->server_started.load(std::memory_order_acquire))
|
||||
{
|
||||
reached_run = true;
|
||||
break;
|
||||
}
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
if (!reached_run)
|
||||
{
|
||||
SCLOGF_FATAL("ServerCore thread failed to schedule within 500ms (port {})", pimpl->port);
|
||||
// 尽力而为的安全收尾:即使线程迟迟没被调度起来,它终究会跑到 Run(),
|
||||
// 而 Run() 会一直阻塞直到 Stop() 生效——所以这里调用 Stop()+join()
|
||||
// 依然能把这个半启动状态收拾干净,不会遗留一个不受控的线程。
|
||||
pimpl->ccServer->Stop();
|
||||
if (pimpl->thServer.joinable())
|
||||
pimpl->thServer.join();
|
||||
return false;
|
||||
}
|
||||
bool running = pimpl->ccServer->IsRunning();
|
||||
if (running)
|
||||
SCLOG_INFO("ServerCore Running");
|
||||
return;
|
||||
else
|
||||
SCLOGF_ERROR("ServerCore failed to start listening on port {}", pimpl->port);
|
||||
return running;
|
||||
}
|
||||
|
||||
void ServerCore::Stop()
|
||||
@@ -106,6 +144,8 @@ void ServerCore::Stop()
|
||||
if (pimpl->ccServer == nullptr)
|
||||
return;
|
||||
pimpl->ccServer->Stop();
|
||||
if (pimpl->thServer.joinable())
|
||||
pimpl->thServer.join();
|
||||
SCLOG_INFO("ServerCore Stopped");
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user