Skip to content

Commit 6f9ad77

Browse files
committed
EventHub: Process sysfs node changes from InputReader thread
Before syfs node change notifications were processed by EventHub, all device openings and closings happened on the InputReader thread. The upper layer (InputReader) makes assumptions about EventHub Device states being synchronized with the notications of device additions and removals from EventHub to InputReader. The addition of sysfs node change processing moved some device openings and closings off of the InputReader thread, which can break the synchronization assumptions in InputReader. In this CL, we move sysfs node change processing to the InputReader thread. Bug: 397208968 Bug: 358694799 Test: Presubmit Flag: EXEMPT bug fix Change-Id: If6d70a12ddf74098c74b8360d31c4967ae6b3d03
1 parent 727cbc0 commit 6f9ad77

3 files changed

Lines changed: 31 additions & 3 deletions

File tree

services/inputflinger/reader/EventHub.cpp

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
26712673
void 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
}

services/inputflinger/reader/InputReader.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,7 @@ bool InputReader::canDispatchToDisplay(int32_t deviceId, ui::LogicalDisplayId di
919919

920920
void InputReader::sysfsNodeChanged(const std::string& sysfsNodePath) {
921921
mEventHub->sysfsNodeChanged(sysfsNodePath);
922+
mEventHub->wake();
922923
}
923924

924925
DeviceId InputReader::getLastUsedInputDeviceId() {

services/inputflinger/reader/include/EventHub.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
#include <batteryservice/BatteryService.h>
3333
#include <ftl/flags.h>
34+
#include <input/BlockingQueue.h>
3435
#include <input/Input.h>
3536
#include <input/InputDevice.h>
3637
#include <input/KeyCharacterMap.h>
@@ -775,6 +776,8 @@ class EventHub : public EventHubInterface {
775776
void addDeviceInputInotify();
776777
void addDeviceInotify();
777778

779+
void handleSysfsNodeChangeNotificationsLocked() REQUIRES(mLock);
780+
778781
// Protect all internal state.
779782
mutable std::mutex mLock;
780783

@@ -824,6 +827,10 @@ class EventHub : public EventHubInterface {
824827
size_t mPendingEventCount;
825828
size_t mPendingEventIndex;
826829
bool mPendingINotify;
830+
831+
// The sysfs node change notifications that have been sent to EventHub.
832+
// Enqueuing notifications does not require the lock to be held.
833+
BlockingQueue<std::string> mChangedSysfsNodeNotifications;
827834
};
828835

829836
} // namespace android

0 commit comments

Comments
 (0)