aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/worldserver/RemoteAccess/RASocket.cpp16
-rw-r--r--src/server/worldserver/RemoteAccess/RASocket.h1
2 files changed, 13 insertions, 4 deletions
diff --git a/src/server/worldserver/RemoteAccess/RASocket.cpp b/src/server/worldserver/RemoteAccess/RASocket.cpp
index 3e9c12b32d8..359abd39901 100644
--- a/src/server/worldserver/RemoteAccess/RASocket.cpp
+++ b/src/server/worldserver/RemoteAccess/RASocket.cpp
@@ -33,6 +33,7 @@
RASocket::RASocket()
{
_minLevel = uint8(ConfigMgr::GetIntDefault("RA.MinLevel", 3));
+ _commandExecuting = false;
}
RASocket::~RASocket()
@@ -59,6 +60,13 @@ int RASocket::handle_close(ACE_HANDLE, ACE_Reactor_Mask)
sLog->outInfo(LOG_FILTER_REMOTECOMMAND, "Closing connection");
peer().close_reader();
wait();
+ // While the above wait() will wait for the ::svc() to finish, it will not wait for the async event
+ // RASocket::commandfinished to be completed. Calling destroy() before the latter function ends
+ // will lead to using a freed pointer -> crash.
+ while (_commandExecuting.value())
+ ACE_OS::sleep(1);
+
+ destroy();
return 0;
}
@@ -149,6 +157,7 @@ int RASocket::process_command(const std::string& command)
return -1;
}
+ _commandExecuting = true;
CliCommandHolder* cmd = new CliCommandHolder(this, command.c_str(), &RASocket::zprint, &RASocket::commandFinished);
sWorld->QueueCliCommand(cmd);
@@ -411,12 +420,11 @@ void RASocket::commandFinished(void* callbackArg, bool /*success*/)
// the message is 0 size control message to tell that command output is finished
// hence we don't put timeout, because it shouldn't increase queue size and shouldn't block
- if (socket->peer().get_handle() == ACE_INVALID_HANDLE // this can happen if this code is triggered when handle_close has already called peer().close_writer()
- || socket->putq(mb->duplicate()) == -1)
+ if (socket->putq(mb->duplicate()) == -1)
// getting here is bad, command can't be marked as complete
sLog->outDebug(LOG_FILTER_REMOTECOMMAND, "Failed to enqueue command end message. Error is %s", ACE_OS::strerror(errno));
mb->release();
- socket->destroy(); // deletes the object
- socket = NULL;
+
+ socket->_commandExecuting = false;
}
diff --git a/src/server/worldserver/RemoteAccess/RASocket.h b/src/server/worldserver/RemoteAccess/RASocket.h
index d23d1f0d5fd..e92cb35eaf0 100644
--- a/src/server/worldserver/RemoteAccess/RASocket.h
+++ b/src/server/worldserver/RemoteAccess/RASocket.h
@@ -57,6 +57,7 @@ class RASocket: public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH>
private:
/// Minimum security level required to connect
uint8 _minLevel;
+ ACE_Atomic_Op<ACE_Thread_Mutex, bool> _commandExecuting;
};
#endif
/// @}