Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit abd3142d authored by Erik Kline's avatar Erik Kline
Browse files

Close netlink socket when shutting down IpReachabilityMonitor

This forces the NetlinkSocketObserver thread to exit quickly, rather
than lingering until the next random netlink neighbor multicast message
arrives.

Additionally, add a small unittest to verify that multiple calls to
NetlinkSocket#close() are safe.

Change-Id: I101730fad7eee72f9c6e8a7e7bd10c634f2ceab4
parent f357c962
Loading
Loading
Loading
Loading
+8 −7
Original line number Diff line number Diff line
@@ -73,7 +73,8 @@ public class IpReachabilityMonitor {
    private final Set<InetAddress> mIpWatchList;
    private int mIpWatchListVersion;
    private boolean mRunning;
    final private Thread mObserverThread;
    private final NetlinkSocketObserver mNetlinkSocketObserver;
    private final Thread mObserverThread;

    public IpReachabilityMonitor(String ifName, Callback callback) throws IllegalArgumentException {
        mInterfaceName = ifName;
@@ -88,15 +89,15 @@ public class IpReachabilityMonitor {
        mIpWatchList = new HashSet<InetAddress>();
        mIpWatchListVersion = 0;
        mRunning = false;
        mObserverThread = new Thread(new NetlinkSocketObserver());
        mNetlinkSocketObserver = new NetlinkSocketObserver();
        mObserverThread = new Thread(mNetlinkSocketObserver);
        mObserverThread.start();
    }

    public void stop() {
        synchronized (mLock) {
            mRunning = false;
            mIpWatchList.clear();
        }
        synchronized (mLock) { mRunning = false; }
        clearLinkProperties();
        mNetlinkSocketObserver.clearNetlinkSocket();
    }

    // TODO: add a public dump() method that can be called during a bug report.
@@ -251,6 +252,7 @@ public class IpReachabilityMonitor {
    }


    // TODO: simply the number of objects by making this extend Thread.
    private final class NetlinkSocketObserver implements Runnable {
        private static final String TAG = "NetlinkSocketObserver";
        private NetlinkSocket mSocket;
@@ -292,7 +294,6 @@ public class IpReachabilityMonitor {
            if (mSocket != null) {
                mSocket.close();
            }
            mSocket = null;
        }

            // TODO: Refactor the main loop to recreate the socket upon recoverable errors.
+23 −0
Original line number Diff line number Diff line
@@ -90,4 +90,27 @@ public class NetlinkSocketTest extends TestCase {

        s.close();
    }

    public void testRepeatedCloseCallsAreQuiet() throws Exception {
        // Create a working NetlinkSocket.
        NetlinkSocket s = new NetlinkSocket(OsConstants.NETLINK_ROUTE);
        assertNotNull(s);
        s.connectToKernel();
        NetlinkSocketAddress localAddr = s.getLocalAddress();
        assertNotNull(localAddr);
        assertEquals(0, localAddr.getGroupsMask());
        assertTrue(0 != localAddr.getPortId());
        // Close once.
        s.close();
        // Test that it is closed.
        boolean expectedErrorSeen = false;
        try {
            localAddr = s.getLocalAddress();
        } catch (ErrnoException e) {
            expectedErrorSeen = true;
        }
        assertTrue(expectedErrorSeen);
        // Close once more.
        s.close();
    }
}