adcsensor: Check if the object is still valid in the async callback functions
Sometimes adcsesnor will crash during stress test.
The root cause is that the object is destroyed already
when the async callback functions are executed.
The timer cancel() cannot cancel the expired callback
handlers. When the callback handler is executed,
the object is deleted already.
The buffer used by async_read_util must guarantee
that they remain valid until the handler is called.
Using the weak_ptr to check if the object is still valid
before using these member variables/functions.
Tested:
No adcsensor crash with stress test,
Change the threshold of ADC sensor 0x51 P3VBAT:
while [ true ]; do; \
ipmitool raw 4 0x26 0x51 0x1b 0x20 0x1b 0 0x2a 0x2a 0;\
ipmitool raw 4 0x26 0x51 0x1b 0x20 0x1b 0 0x2a 0x2b 0;\
sleep 1; done
Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
Change-Id: I2ddb934199e2d0f52a1a6df25c46eadfe06cfda3
diff --git a/src/ADCSensorMain.cpp b/src/ADCSensorMain.cpp
index 1b56d93..df35722 100644
--- a/src/ADCSensorMain.cpp
+++ b/src/ADCSensorMain.cpp
@@ -65,7 +65,7 @@
void createSensors(
boost::asio::io_service& io, sdbusplus::asio::object_server& objectServer,
- boost::container::flat_map<std::string, std::unique_ptr<ADCSensor>>&
+ boost::container::flat_map<std::string, std::shared_ptr<ADCSensor>>&
sensors,
std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
const std::unique_ptr<boost::container::flat_set<std::string>>&
@@ -269,10 +269,11 @@
}
}
- sensor = std::make_unique<ADCSensor>(
+ sensor = std::make_shared<ADCSensor>(
path.string(), objectServer, dbusConnection, io, sensorName,
std::move(sensorThresholds), scaleFactor, readState,
*interfacePath, std::move(bridgeGpio));
+ sensor->setupRead();
}
}));
@@ -286,7 +287,7 @@
auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
systemBus->request_name("xyz.openbmc_project.ADCSensor");
sdbusplus::asio::object_server objectServer(systemBus);
- boost::container::flat_map<std::string, std::unique_ptr<ADCSensor>> sensors;
+ boost::container::flat_map<std::string, std::shared_ptr<ADCSensor>> sensors;
std::vector<std::unique_ptr<sdbusplus::bus::match::match>> matches;
std::unique_ptr<boost::container::flat_set<std::string>> sensorsChanged =
std::make_unique<boost::container::flat_set<std::string>>();