summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Pelly <npelly@google.com>2010-01-20 19:36:49 -0800
committerNick Pelly <npelly@google.com>2010-01-20 19:56:24 -0800
commite6b1bbd8acca3f6e174c24cf4eb23a66db2d08a2 (patch)
tree6f56ac4d7205d451885c5eaf258dd28b3d45f23f
parent8c166512a7e6ffaf87e41cd3a85d55993648fe9b (diff)
downloadframeworks_base-e6b1bbd8acca3f6e174c24cf4eb23a66db2d08a2.zip
frameworks_base-e6b1bbd8acca3f6e174c24cf4eb23a66db2d08a2.tar.gz
frameworks_base-e6b1bbd8acca3f6e174c24cf4eb23a66db2d08a2.tar.bz2
Fix failure to open AVRCP input device due to EPERM.
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
-rw-r--r--libs/ui/EventHub.cpp10
1 files changed, 8 insertions, 2 deletions
diff --git a/libs/ui/EventHub.cpp b/libs/ui/EventHub.cpp
index e39a357..4aac455 100644
--- a/libs/ui/EventHub.cpp
+++ b/libs/ui/EventHub.cpp
@@ -489,6 +489,7 @@ int EventHub::open_device(const char *deviceName)
{
int version;
int fd;
+ int attempt;
struct pollfd *new_mFDs;
device_t **new_devices;
char **new_device_names;
@@ -500,12 +501,17 @@ int EventHub::open_device(const char *deviceName)
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));