Sleep for 100us and try to open the input device again if it fails, with a
maximum of 10 attempts.
We need the retry logic because setting permissions on a new input device is
racy. The init process watches for new input device (via uevent) and sets the
permission on them in devices.c:make_device(). However at the same time
EventHub.cpp watches for new input devices from the system_server process, and
immediately tries to open them. I can't see a simple way to avoid this race
condition.
As best as I can tell this race condition has always exisited.
There must have been some timing change that happened recently that causes us
to hit this race condition much more often. See repro notes in referenced bug.
Bug:
2375632
{
int version;
int fd;
+ int attempt;
struct pollfd *new_mFDs;
device_t **new_devices;
char **new_device_names;
LOGV("Opening device: %s", deviceName);
AutoMutex _l(mLock);
-
- fd = open(deviceName, O_RDWR);
+
+ for (attempt = 0; attempt < 10; attempt++) {
+ fd = open(deviceName, O_RDWR);
+ if (fd >= 0) break;
+ usleep(100);
+ }
if(fd < 0) {
LOGE("could not open %s, %s\n", deviceName, strerror(errno));
return -1;
}
+ LOGV("Opened device: %s (%d failures)", deviceName, attempt);
if(ioctl(fd, EVIOCGVERSION, &version)) {
LOGE("could not get driver version for %s, %s\n", deviceName, strerror(errno));