- @SuppressWarnings("unchecked")
- public <T extends RpcService> RpcRouter<T> getRpcRouter(Class<T> type) {
- RpcRouter<?> potentialRouter = rpcRouters.get(type);
- if (potentialRouter != null) {
- return (RpcRouter<T>) potentialRouter;
- }
- synchronized (this) {
- /**
- * Potential Router could be instantiated by other thread while we
- * were waiting for the lock.
- */
- potentialRouter = rpcRouters.get(type);
- if (potentialRouter != null) {
- return (RpcRouter<T>) potentialRouter;
+
+ public <T extends RpcService> RpcRouter<T> getRpcRouter(final Class<T> type) {
+ try {
+ final AtomicBoolean created = new AtomicBoolean(false);
+ @SuppressWarnings( "unchecked")
+ // LoadingCache is unsuitable for RpcRouter since we need to distinguish
+ // first creation of RPC Router, so that is why
+ // we are using normal cache with load API and shared AtomicBoolean
+ // for this call, which will be set to true if router was created.
+ RpcRouter<T> router = (RpcRouter<T>) rpcRouters.get(type,new Callable<RpcRouter<?>>() {
+
+ @Override
+ public org.opendaylight.controller.sal.binding.api.rpc.RpcRouter<?> call() {
+ RpcRouter<?> router = rpcFactory.getRouterFor(type, name);
+ router.registerRouteChangeListener(new RouteChangeForwarder<T>(type));
+ LOG.debug("Registering router {} as global implementation of {} in {}", router, type.getSimpleName(), this);
+ RuntimeCodeHelper.setDelegate(getRpcService(type), router.getInvocationProxy());
+ created.set(true);
+ return router;
+ }
+ });
+ if(created.get()) {
+ notifyListenersRoutedCreated(router);