[ntcore] Don't deadlock server on early destroy (#4863)

It was possible to deadlock on instance destroy if the server had started
but had not yet fully initialized its handles.
This commit is contained in:
Peter Johnson
2022-12-27 10:25:48 -08:00
committed by GitHub
parent 2ac41f3edc
commit 6cfe5de00d
2 changed files with 17 additions and 5 deletions

View File

@@ -113,12 +113,15 @@ void InstanceImpl::StartServer(std::string_view persistFilename,
}
void InstanceImpl::StopServer() {
std::scoped_lock lock{m_mutex};
if ((networkMode & NT_NET_MODE_SERVER) == 0) {
return;
std::shared_ptr<NetworkServer> server;
{
std::scoped_lock lock{m_mutex};
if ((networkMode & NT_NET_MODE_SERVER) == 0) {
return;
}
server = std::move(m_networkServer);
networkMode = NT_NET_MODE_NONE;
}
m_networkServer.reset();
networkMode = NT_NET_MODE_NONE;
}
void InstanceImpl::StartClient3(std::string_view identity) {

View File

@@ -108,6 +108,7 @@ class NSImpl {
unsigned int port3, unsigned int port4,
net::ILocalStorage& localStorage, IConnectionList& connList,
wpi::Logger& logger, std::function<void()> initDone);
~NSImpl();
void HandleLocal();
void LoadPersistent();
@@ -131,6 +132,7 @@ class NSImpl {
std::shared_ptr<uv::Timer> m_savePersistentTimer;
std::shared_ptr<uv::Async<>> m_flushLocal;
std::shared_ptr<uv::Async<>> m_flush;
bool m_shutdown = false;
std::vector<net::ClientMessage> m_localMsgs;
@@ -344,6 +346,10 @@ NSImpl::NSImpl(std::string_view persistentFilename,
});
}
NSImpl::~NSImpl() {
m_loopRunner.ExecAsync([this](uv::Loop&) { m_shutdown = true; });
}
void NSImpl::HandleLocal() {
m_localQueue.ReadQueue(&m_localMsgs);
m_serverImpl.HandleLocal(m_localMsgs);
@@ -395,6 +401,9 @@ void NSImpl::SavePersistent(std::string_view filename, std::string_view data) {
}
void NSImpl::Init() {
if (m_shutdown) {
return;
}
auto errs = m_serverImpl.LoadPersistent(m_persistentData);
if (!errs.empty()) {
WARNING("error reading persistent file: {}", errs);