BUG-956 deadlock by rpc invocation - phase2
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / sal / OFRpcTask.java
index b153fcc420f8c13ae8cf6a4cb15342278b1262d8..79764f9dd09df8ec5e29b2c7707e0edfab7d4cc3 100644 (file)
@@ -7,38 +7,36 @@
  */
 package org.opendaylight.openflowplugin.openflow.md.core.sal;
 
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.openflowplugin.openflow.md.core.SwitchConnectionDistinguisher;
 import org.opendaylight.openflowplugin.openflow.md.core.session.IMessageDispatchService;
 import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContext;
 
-import com.google.common.util.concurrent.SettableFuture;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
 
 /**
  * @param <T> input type
  * @param <K> future output type
  */
-public abstract class OFRpcTask<T, K> implements Runnable {
+public abstract class OFRpcTask<T, K> implements Callable<ListenableFuture<K>> {
     
-    private SwitchConnectionDistinguisher cookie;
-    private IMessageDispatchService messageService;
-    private SessionContext session;
+    private OFRpcTaskContext taskContext;
     private T input;
-    private SettableFuture<K> result;
-    private NotificationProviderService rpcNotificationProviderService;
-    
-    /**
-     * @return the result
-     */
-    public SettableFuture<K> getResult() {
-        return result;
-    }
+    private SwitchConnectionDistinguisher cookie;
     
     /**
-     * @param result the result to set
+     * @param taskContext
+     * @param input 
+     * @param cookie 
      */
-    public void setResult(SettableFuture<K> result) {
-        this.result = result;
+    public OFRpcTask(OFRpcTaskContext taskContext, SwitchConnectionDistinguisher cookie, T input) {
+        this.taskContext = taskContext;
+        this.cookie = cookie;
+        this.input = input;
     }
 
     /**
@@ -49,73 +47,86 @@ public abstract class OFRpcTask<T, K> implements Runnable {
     }
 
     /**
-     * @return the messageService
+     * @param cookie the cookie to set
      */
-    public IMessageDispatchService getMessageService() {
-        return messageService;
+    public void setCookie(SwitchConnectionDistinguisher cookie) {
+        this.cookie = cookie;
     }
 
     /**
-     * @return the session
+     * @return the input
      */
-    public SessionContext getSession() {
-        return session;
+    public T getInput() {
+        return input;
     }
-    
+
     /**
-     * @return protocol version
+     * @param input the input to set
      */
-    public Short getVersion() {
-        return session.getFeatures().getVersion();
+    public void setInput(T input) {
+        this.input = input;
     }
 
     /**
-     * @param cookie the cookie to set
+     * @return the rpcNotificationProviderService
      */
-    public void setCookie(SwitchConnectionDistinguisher cookie) {
-        this.cookie = cookie;
+    public NotificationProviderService getRpcNotificationProviderService() {
+        return taskContext.getRpcNotificationProviderService();
     }
 
     /**
-     * @param messageService the messageService to set
+     * @return message service
+     * @see org.opendaylight.openflowplugin.openflow.md.core.sal.OFRpcTaskContext#getMessageService()
      */
-    public void setMessageService(IMessageDispatchService messageService) {
-        this.messageService = messageService;
+    public IMessageDispatchService getMessageService() {
+        return taskContext.getMessageService();
     }
 
     /**
-     * @param session the session to set
+     * @return session
+     * @see org.opendaylight.openflowplugin.openflow.md.core.sal.OFRpcTaskContext#getSession()
      */
-    public void setSession(SessionContext session) {
-        this.session = session;
+    public SessionContext getSession() {
+        return taskContext.getSession();
     }
 
     /**
-     * @return the input
+     * @return max timeout
+     * @see org.opendaylight.openflowplugin.openflow.md.core.sal.OFRpcTaskContext#getMaxTimeout()
      */
-    public T getInput() {
-        return input;
+    public long getMaxTimeout() {
+        return taskContext.getMaxTimeout();
     }
 
     /**
-     * @param input the input to set
+     * @return time unit for max timeout
+     * @see org.opendaylight.openflowplugin.openflow.md.core.sal.OFRpcTaskContext#getMaxTimeoutUnit()
      */
-    public void setInput(T input) {
-        this.input = input;
+    public TimeUnit getMaxTimeoutUnit() {
+        return taskContext.getMaxTimeoutUnit();
     }
-
+    
     /**
-     * @param rpcNotificationProviderService
+     * @return protocol version
      */
-    public void setRpcNotificationProviderService(
-            NotificationProviderService rpcNotificationProviderService) {
-                this.rpcNotificationProviderService = rpcNotificationProviderService;
+    public Short getVersion() {
+        return taskContext.getSession().getFeatures().getVersion();
+        
     }
     
     /**
-     * @return the rpcNotificationProviderService
+     * @return the taskContext
      */
-    public NotificationProviderService getRpcNotificationProviderService() {
-        return rpcNotificationProviderService;
+    public OFRpcTaskContext getTaskContext() {
+        return taskContext;
+    }
+    
+    /**
+     * submit task into rpc worker pool
+     * @return future result of task 
+     */
+    public ListenableFuture<K> submit() {
+        ListenableFuture<ListenableFuture<K>> compoundResult = getTaskContext().getRpcPool().submit(this);
+        return Futures.dereference(compoundResult);
     }
 }