ONOS-3586: Move event handling in HostLocationProvider to a background thread to avoid hogging event dispatcher thread

Change-Id: I41ada7a946743854228594345cb636d1c336a2af
diff --git a/providers/host/src/main/java/org/onosproject/provider/host/impl/HostLocationProvider.java b/providers/host/src/main/java/org/onosproject/provider/host/impl/HostLocationProvider.java
index 93f6bf8..30cfb40 100644
--- a/providers/host/src/main/java/org/onosproject/provider/host/impl/HostLocationProvider.java
+++ b/providers/host/src/main/java/org/onosproject/provider/host/impl/HostLocationProvider.java
@@ -67,8 +67,11 @@
 
 import java.util.Dictionary;
 import java.util.Set;
+import java.util.concurrent.ExecutorService;
 
 import static com.google.common.base.Strings.isNullOrEmpty;
+import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
+import static org.onlab.util.Tools.groupedThreads;
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
@@ -117,6 +120,8 @@
                     "Host Location Provider; default is false")
     private boolean ipv6NeighborDiscovery = false;
 
+    protected ExecutorService eventHandler;
+
     /**
      * Creates an OpenFlow host provider.
      */
@@ -128,7 +133,7 @@
     public void activate(ComponentContext context) {
         cfgService.registerProperties(getClass());
         appId = coreService.registerApplication("org.onosproject.provider.host");
-
+        eventHandler = newSingleThreadScheduledExecutor(groupedThreads("onos/host-loc-provider", "event-handler"));
         providerService = providerRegistry.register(this);
         packetService.addProcessor(processor, PacketProcessor.advisor(1));
         deviceService.addListener(deviceListener);
@@ -147,6 +152,7 @@
         providerRegistry.unregister(this);
         packetService.removeProcessor(processor);
         deviceService.removeListener(deviceListener);
+        eventHandler.shutdown();
         providerService = null;
         log.info("Stopped");
     }
@@ -392,6 +398,10 @@
     private class InternalDeviceListener implements DeviceListener {
         @Override
         public void event(DeviceEvent event) {
+            eventHandler.execute(() -> handleEvent(event));
+        }
+
+        private void handleEvent(DeviceEvent event) {
             Device device = event.subject();
             switch (event.type()) {
                 case DEVICE_ADDED: