Fix issues related to removing Looper callbacks after close.
When a file descriptor is closed before removing it from the
epoll set, it will normally be removed automatically from the
epoll set by the kernel. However if there exists a duplicate
then the original file descriptor may remain in the set and
continue to receive events until all duplicates have been closed.
Unfortunately due to kernel limitations we need to rebuild the epoll
set from scratch because it may contain an old file handle that we are
now unable to remove since its file descriptor is no longer valid.
No such problem would have occurred if we were using the poll system
call instead, but that approach carries others disadvantages.
Bug: 19715279
Change-Id: If1ab8ebda0825755a416d513e888942a02ee3948
diff --git a/include/utils/Looper.h b/include/utils/Looper.h
index 5722c8e..a381251 100644
--- a/include/utils/Looper.h
+++ b/include/utils/Looper.h
@@ -420,9 +420,12 @@
struct Request {
int fd;
int ident;
+ int events;
int seq;
sp<LooperCallback> callback;
void* data;
+
+ void initEventItem(struct epoll_event* eventItem) const;
};
struct Response {
@@ -455,7 +458,8 @@
// any use of it is racy anyway.
volatile bool mPolling;
- int mEpollFd; // immutable
+ int mEpollFd; // guarded by mLock but only modified on the looper thread
+ bool mEpollRebuildRequired; // guarded by mLock
// Locked list of file descriptor monitoring requests.
KeyedVector<int, Request> mRequests; // guarded by mLock
@@ -471,9 +475,12 @@
int removeFd(int fd, int seq);
void awoken();
void pushResponse(int events, const Request& request);
+ void rebuildEpollLocked();
+ void scheduleEpollRebuildLocked();
static void initTLSKey();
static void threadDestructor(void *st);
+ static void initEpollEvent(struct epoll_event* eventItem);
};
} // namespace android