Fix the heap-use-after-free risk caused by direct deconstruction when it is not used after initialization. (#274)
Fix the heap-use-after-free risk caused by direct deconstruction when it is not used after initialization. (#274)
diff --git a/src/MQClientFactory.cpp b/src/MQClientFactory.cpp
index d210965..6f76209 100644
--- a/src/MQClientFactory.cpp
+++ b/src/MQClientFactory.cpp
@@ -62,8 +62,6 @@
m_topicRouteTable.clear();
m_brokerAddrTable.clear();
m_topicPublishInfoTable.clear();
-
- m_pClientAPIImpl = NULL;
}
void MQClientFactory::start() {
@@ -287,26 +285,36 @@
return;
switch (m_serviceState) {
+ case CREATE_JUST:
case RUNNING: {
if (m_consumer_async_service_thread) {
m_consumer_async_ioService.stop();
m_consumer_async_service_thread->interrupt();
m_consumer_async_service_thread->join();
+ m_consumer_async_service_thread.reset();
}
- m_async_ioService.stop();
- m_async_service_thread->interrupt();
- m_async_service_thread->join();
- m_pClientAPIImpl->stopAllTcpTransportThread(); // Note: stop all
- // TcpTransport Threads
- // and release all
- // responseFuture
- // conditions
+
+ if (m_async_service_thread) {
+ m_async_ioService.stop();
+ m_async_service_thread->interrupt();
+ m_async_service_thread->join();
+ m_async_service_thread.reset();
+ }
+
+ if (m_pClientAPIImpl) {
+ m_pClientAPIImpl->stopAllTcpTransportThread(); // Note: stop all
+ // TcpTransport Threads
+ // and release all
+ // responseFuture
+ // conditions
+ m_pClientAPIImpl.reset();
+ }
+
m_serviceState = SHUTDOWN_ALREADY;
LOG_INFO("MQClientFactory:%s shutdown", m_clientId.c_str());
break;
}
case SHUTDOWN_ALREADY:
- case CREATE_JUST:
break;
default:
break;
diff --git a/test/src/MQClientManagerTest.cpp b/test/src/MQClientManagerTest.cpp
index 830be46..78b336b 100644
--- a/test/src/MQClientManagerTest.cpp
+++ b/test/src/MQClientManagerTest.cpp
@@ -36,6 +36,7 @@
MQClientFactory* factory = MQClientManager::getInstance()->getMQClientFactory(clientId, 1, 1000, 3000, unitName);
MQClientFactory* factory2 = MQClientManager::getInstance()->getMQClientFactory(clientId, 1, 1000, 3000, unitName);
EXPECT_EQ(factory, factory2);
+ factory->shutdown();
MQClientManager::getInstance()->removeClientFactory(clientId);
}