@@ -1897,6 +1897,8 @@ std::vector<RawEvent> EventHub::getEvents(int timeoutMillis) {
18971897 break ; // return to the caller before we actually rescan
18981898 }
18991899
1900+ handleSysfsNodeChangeNotificationsLocked ();
1901+
19001902 // Report any devices that had last been added/removed.
19011903 for (auto it = mClosingDevices .begin (); it != mClosingDevices .end ();) {
19021904 std::unique_ptr<Device> device = std::move (*it);
@@ -2669,12 +2671,25 @@ status_t EventHub::disableDevice(int32_t deviceId) {
26692671// NETLINK socket to observe UEvents. We can create similar infrastructure on Eventhub side to
26702672// directly observe UEvents instead of triggering from Java side.
26712673void EventHub::sysfsNodeChanged (const std::string& sysfsNodePath) {
2672- std::scoped_lock _l (mLock );
2674+ mChangedSysfsNodeNotifications .emplace (sysfsNodePath);
2675+ }
2676+
2677+ void EventHub::handleSysfsNodeChangeNotificationsLocked () {
2678+ // Use a set to de-dup any repeated notifications.
2679+ std::set<std::string> changedNodes;
2680+ while (true ) {
2681+ auto node = mChangedSysfsNodeNotifications .popWithTimeout (std::chrono::nanoseconds (0 ));
2682+ if (!node.has_value ()) break ;
2683+ changedNodes.emplace (*node);
2684+ }
2685+ if (changedNodes.empty ()) {
2686+ return ;
2687+ }
26732688
26742689 // Testing whether a sysfs node changed involves several syscalls, so use a cache to avoid
26752690 // testing the same node multiple times.
26762691 std::map<std::shared_ptr<const AssociatedDevice>, bool /* changed*/ > testedDevices;
2677- auto isAssociatedDeviceChanged = [&testedDevices, &sysfsNodePath ](const Device& dev) {
2692+ auto isAssociatedDeviceChanged = [&testedDevices, &changedNodes ](const Device& dev) {
26782693 if (!dev.associatedDevice ) {
26792694 return false ;
26802695 }
@@ -2683,7 +2698,12 @@ void EventHub::sysfsNodeChanged(const std::string& sysfsNodePath) {
26832698 return testedIt->second ;
26842699 }
26852700 // Cache miss
2686- if (sysfsNodePath.find (dev.associatedDevice ->sysfsRootPath .string ()) == std::string::npos) {
2701+ const bool anyNodesChanged =
2702+ std::any_of (changedNodes.begin (), changedNodes.end (), [&](const std::string& node) {
2703+ return node.find (dev.associatedDevice ->sysfsRootPath .string ()) !=
2704+ std::string::npos;
2705+ });
2706+ if (!anyNodesChanged) {
26872707 testedDevices.emplace (dev.associatedDevice , false );
26882708 return false ;
26892709 }
0 commit comments