Skip to content
Commit c16b7755 authored by David Pursell's avatar David Pursell
Browse files

MessageQueue: explicitly remove FD event listeners.

When removing an FD listener from a MessageQueue, the MessageQueue waits
until the next event callback on that FD to remove it from the
underlying native Looper.

This works as expected most of the time, but due to the epoll rebuild
logic in the native Looper, there is a rare condition where FDs can get
stuck in the Looper:
  1. Register two or more FD listeners.
  2. Unregister FD1 listener and close FD1.
  3. Before the Looper processes FD1, get an event on FD2 and close it.
(3) will trigger a rebuild of the epoll set but as FD1 is no longer
valid it cannot be added back to the epoll set, and the MessageQueue
will never get the final callback to clean it up.

Each time this happens:
 * There is a small memory leak (24-32 bytes) in native Looper
 * Rebuilding the epoll set incurs slightly more processing
 * An error is logged for each lost FD on each epoll rebuild
This is fairly minimal, and does get cleaned up if the lost FDs is
re-opened during an epoll rebuild (since it can now be added back in),
but worst-case if a process somehow triggers this on a large number of
FDs it might be noticeable.

It seems worth it to just remove the FD explicitly right away to avoid
this case altogether.

Bug: 64083817
Test: [aosp_x86-userdebug emulator] adb shell am instrument -w \
    -e class android.os.cts.MessageQueueTest \
    android.os.cts/android.support.test.runner.AndroidJUnitRunner

Change-Id: I33faca37678439f4b28a4138efcdd80ea8952ab2
parent 95372e87
Loading
Loading
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment