You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by tj...@apache.org on 2017/04/19 13:16:09 UTC

svn commit: r1791915 - in /felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject: ActivateMethod.java BaseMethod.java BindMethod.java

Author: tjwatson
Date: Wed Apr 19 13:16:09 2017
New Revision: 1791915

URL: http://svn.apache.org/viewvc?rev=1791915&view=rev
Log:
FELIX-5615 - Global lock in BaseMethod.NotResolved::resolve method causes deadlock

Modified:
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/ActivateMethod.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/BaseMethod.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/BindMethod.java

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/ActivateMethod.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/ActivateMethod.java?rev=1791915&r1=1791914&r2=1791915&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/ActivateMethod.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/ActivateMethod.java Wed Apr 19 13:16:09 2017
@@ -36,7 +36,7 @@ import org.osgi.service.component.Compon
 import org.osgi.service.log.LogService;
 
 
-public class ActivateMethod extends BaseMethod<ActivatorParameter> implements ComponentMethod
+public class ActivateMethod extends BaseMethod<ActivatorParameter, Object> implements ComponentMethod
 {
 
     protected static final Class<?> COMPONENT_CONTEXT_CLASS = ComponentContext.class;
@@ -59,7 +59,7 @@ public class ActivateMethod extends Base
 
 
     @Override
-    protected Method doFindMethod( Class<?> targetClass, boolean acceptPrivate, boolean acceptPackage, SimpleLogger logger )
+    protected MethodInfo<Object> doFindMethod( Class<?> targetClass, boolean acceptPrivate, boolean acceptPackage, SimpleLogger logger )
         throws SuitableMethodNotAccessibleException, InvocationTargetException
     {
 
@@ -72,7 +72,7 @@ public class ActivateMethod extends Base
                 { COMPONENT_CONTEXT_CLASS }, acceptPrivate, acceptPackage, logger );
             if ( method != null )
             {
-                return method;
+                return new MethodInfo<Object>(method);
             }
         }
         catch ( SuitableMethodNotAccessibleException thrown )
@@ -94,7 +94,7 @@ public class ActivateMethod extends Base
                     {
                         if ( accept( m, acceptPrivate, acceptPackage, returnValue() ) )
                         {
-                            return m;
+                            return new MethodInfo<Object>(m);
                         }
                         suitableMethodNotAccessible = true;
                     }
@@ -102,7 +102,7 @@ public class ActivateMethod extends Base
                     {
                         if ( accept( m, acceptPrivate, acceptPackage, returnValue() ) )
                         {
-                            return m;
+                            return new MethodInfo<Object>(m);
                         }
                         suitableMethodNotAccessible = true;
                     }
@@ -110,7 +110,7 @@ public class ActivateMethod extends Base
                     {
                         if ( accept( m, acceptPrivate, acceptPackage, returnValue() ) )
                         {
-                            return m;
+                            return new MethodInfo<Object>(m);
                         }
                         suitableMethodNotAccessible = true;
                     }
@@ -118,7 +118,7 @@ public class ActivateMethod extends Base
                     {
                         if ( accept( m, acceptPrivate, acceptPackage, returnValue() ) )
                         {
-                            return m;
+                            return new MethodInfo<Object>(m);
                         }
                         suitableMethodNotAccessible = true;
                     }
@@ -126,7 +126,7 @@ public class ActivateMethod extends Base
                     {
                         if ( accept( m, acceptPrivate, acceptPackage, returnValue() ) )
                         {
-                            return m;
+                            return new MethodInfo<Object>(m);
                         }
                         suitableMethodNotAccessible = true;
                     }
@@ -152,7 +152,7 @@ public class ActivateMethod extends Base
                     {
                         if ( accept( m, acceptPrivate, acceptPackage, returnValue() ) )
                         {
-                            return m;
+                            return new MethodInfo<Object>(m);
                         }
                         suitableMethodNotAccessible = true;
                     }
@@ -162,7 +162,7 @@ public class ActivateMethod extends Base
                 {
                     if ( accept( m, acceptPrivate, acceptPackage, returnValue() ) )
                     {
-                        return m;
+                        return new MethodInfo<Object>(m);
                     }
                     suitableMethodNotAccessible = true;
                 }
@@ -178,6 +178,11 @@ public class ActivateMethod extends Base
         return null;
     }
 
+    @Override
+    protected void setTypes(Object types)
+    {
+        // Don't care about types
+    }
 
     boolean isDeactivate()
     {

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/BaseMethod.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/BaseMethod.java?rev=1791915&r1=1791914&r2=1791915&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/BaseMethod.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/BaseMethod.java Wed Apr 19 13:16:09 2017
@@ -36,7 +36,7 @@ import org.osgi.service.log.LogService;
 /**
  * Component method to be invoked on service (un)binding.
  */
-public abstract class BaseMethod<P>
+public abstract class BaseMethod<P, T>
 {
 
     private final DSVersion dsVersion;
@@ -103,16 +103,18 @@ public abstract class BaseMethod<P>
         return m_componentClass;
     }
 
+    protected abstract void setTypes(T types);
 
-    void setMethod( Method method, SimpleLogger logger )
+    synchronized void setMethod(MethodInfo<T> methodInfo, SimpleLogger logger)
     {
-        this.m_method = method;
+        this.m_method = methodInfo == null ? null : methodInfo.getMethod();
 
-        if ( method != null )
+        if (m_method != null)
         {
+            setTypes(methodInfo.getTypes());
             m_state = Resolved.INSTANCE;
             logger.log( LogService.LOG_DEBUG, "Found {0} method: {1}", new Object[]
-                { getMethodNamePrefix(), method }, null );
+            { getMethodNamePrefix(), m_method }, null);
         }
         else if ( m_methodRequired )
         {
@@ -149,7 +151,7 @@ public abstract class BaseMethod<P>
      *      trying to find the requested method.
      * @param logger
      */
-    private Method findMethod( SimpleLogger logger ) throws InvocationTargetException
+    private MethodInfo<T> findMethod(SimpleLogger logger) throws InvocationTargetException
     {
         boolean acceptPrivate = getDSVersion().isDS11();
         boolean acceptPackage = getDSVersion().isDS11();
@@ -170,7 +172,9 @@ public abstract class BaseMethod<P>
 
             try
             {
-                Method method = doFindMethod( theClass, acceptPrivate, acceptPackage, logger );
+                MethodInfo<T> method = doFindMethod(theClass, acceptPrivate,
+                    acceptPackage,
+                    logger);
                 if ( method != null )
                 {
                     return method;
@@ -207,7 +211,8 @@ public abstract class BaseMethod<P>
     }
 
 
-    protected abstract Method doFindMethod( final Class<?> targetClass, final boolean acceptPrivate,
+    protected abstract MethodInfo<T> doFindMethod(final Class<?> targetClass,
+        final boolean acceptPrivate,
             final boolean acceptPackage, SimpleLogger logger ) throws SuitableMethodNotAccessibleException, InvocationTargetException;
 
 
@@ -515,14 +520,41 @@ public abstract class BaseMethod<P>
         return m_state.methodExists( this, logger );
     }
 
+    protected static final class MethodInfo<T>
+    {
+        private final Method m_method;
+        private final T m_types;
+
+        public MethodInfo(Method m)
+        {
+            this(m, null);
+        }
+
+        public MethodInfo(Method m, T types)
+        {
+            m_method = m;
+            m_types = types;
+        }
+
+        public Method getMethod()
+        {
+            return m_method;
+        }
+
+        public T getTypes()
+        {
+            return m_types;
+        }
+    }
+
     private static interface State
     {
 
-        <P> MethodResult invoke( final BaseMethod<P> baseMethod, final Object componentInstance, final P rawParameter, SimpleLogger logger )
+        <P, T> MethodResult invoke( final BaseMethod<P, T> baseMethod, final Object componentInstance, final P rawParameter, SimpleLogger logger )
             throws InvocationTargetException;
 
 
-        <P> boolean methodExists( final BaseMethod<P> baseMethod, SimpleLogger logger );
+        <P, T> boolean methodExists( final BaseMethod<P, T> baseMethod, SimpleLogger logger );
     }
 
     private static class NotApplicable implements State
@@ -531,13 +563,13 @@ public abstract class BaseMethod<P>
         private static final State INSTANCE = new NotApplicable();
 
 
-        public <P> MethodResult invoke( final BaseMethod<P> baseMethod, final Object componentInstance, final P rawParameter, SimpleLogger logger )
+        public <P, T> MethodResult invoke( final BaseMethod<P, T> baseMethod, final Object componentInstance, final P rawParameter, SimpleLogger logger )
         {
             return MethodResult.VOID;
         }
 
 
-        public <P> boolean methodExists( final BaseMethod<P> baseMethod, SimpleLogger logger )
+        public <P, T> boolean methodExists( final BaseMethod<P, T> baseMethod, SimpleLogger logger )
         {
             return true;
         }
@@ -548,13 +580,14 @@ public abstract class BaseMethod<P>
         private static final State INSTANCE = new NotResolved();
 
 
-        private synchronized <P> void resolve( final BaseMethod<P> baseMethod, SimpleLogger logger )
+        private <P, T> void resolve(final BaseMethod<P, T> baseMethod,
+            SimpleLogger logger)
         {
             logger.log( LogService.LOG_DEBUG, "getting {0}: {1}", new Object[]
                     {baseMethod.getMethodNamePrefix(), baseMethod.getMethodName()}, null );
 
             // resolve the method
-            Method method = null;
+            MethodInfo<T> method = null;
             try
             {
                 method = baseMethod.findMethod( logger );
@@ -569,7 +602,7 @@ public abstract class BaseMethod<P>
         }
 
 
-        public <P> MethodResult invoke( final BaseMethod<P> baseMethod, final Object componentInstance, final P rawParameter, SimpleLogger logger )
+        public <P, T> MethodResult invoke( final BaseMethod<P, T> baseMethod, final Object componentInstance, final P rawParameter, SimpleLogger logger )
             throws InvocationTargetException
         {
             resolve( baseMethod, logger );
@@ -577,7 +610,7 @@ public abstract class BaseMethod<P>
         }
 
 
-        public <P> boolean methodExists( final BaseMethod<P> baseMethod, SimpleLogger logger )
+        public <P, T> boolean methodExists( final BaseMethod<P, T> baseMethod, SimpleLogger logger )
         {
             resolve( baseMethod, logger );
             return baseMethod.getState().methodExists( baseMethod, logger );
@@ -589,7 +622,7 @@ public abstract class BaseMethod<P>
         private static final State INSTANCE = new NotFound();
 
 
-        public <P> MethodResult invoke( final BaseMethod<P> baseMethod, final Object componentInstance, final P rawParameter, SimpleLogger logger )
+        public <P, T> MethodResult invoke( final BaseMethod<P, T> baseMethod, final Object componentInstance, final P rawParameter, SimpleLogger logger )
         {
             // 112.3.1 If the method is not found , SCR must log an error
             // message with the log service, if present, and ignore the
@@ -600,7 +633,7 @@ public abstract class BaseMethod<P>
         }
 
 
-        public <P> boolean methodExists( final BaseMethod<P> baseMethod, SimpleLogger logger )
+        public <P, T> boolean methodExists( final BaseMethod<P, T> baseMethod, SimpleLogger logger )
         {
             return false;
         }
@@ -611,14 +644,14 @@ public abstract class BaseMethod<P>
         private static final State INSTANCE = new Resolved();
 
 
-        public <P> MethodResult invoke( final BaseMethod<P> baseMethod, final Object componentInstance, final P rawParameter, SimpleLogger logger )
+        public <P, T> MethodResult invoke( final BaseMethod<P, T> baseMethod, final Object componentInstance, final P rawParameter, SimpleLogger logger )
             throws InvocationTargetException
         {
             return baseMethod.invokeMethod( componentInstance, rawParameter, logger );
         }
 
 
-        public <P> boolean methodExists( final BaseMethod<P> baseMethod, SimpleLogger logger )
+        public <P, T> boolean methodExists( final BaseMethod<P, T> baseMethod, SimpleLogger logger )
         {
             return true;
         }

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/BindMethod.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/BindMethod.java?rev=1791915&r1=1791914&r2=1791915&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/BindMethod.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/inject/BindMethod.java Wed Apr 19 13:16:09 2017
@@ -26,10 +26,10 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.felix.scr.impl.helper.ComponentServiceObjectsHelper;
 import org.apache.felix.scr.impl.helper.MethodResult;
 import org.apache.felix.scr.impl.helper.ReadOnlyDictionary;
 import org.apache.felix.scr.impl.helper.SimpleLogger;
+import org.apache.felix.scr.impl.inject.BindMethod.ParamType;
 import org.apache.felix.scr.impl.manager.ComponentContextImpl;
 import org.apache.felix.scr.impl.manager.RefPair;
 import org.apache.felix.scr.impl.metadata.DSVersion;
@@ -40,12 +40,12 @@ import org.osgi.service.log.LogService;
 /**
  * Component method to be invoked on service (un)binding.
  */
-public class BindMethod extends BaseMethod<BindParameters>
+public class BindMethod extends BaseMethod<BindParameters, List<BindMethod.ParamType>>
 implements org.apache.felix.scr.impl.helper.ReferenceMethod
 {
     private final String m_referenceClassName;
 
-    private enum ParamType {
+    enum ParamType {
         serviceReference,
         serviceObjects,
         serviceType,
@@ -83,7 +83,7 @@ implements org.apache.felix.scr.impl.hel
      *      trying to find the requested method.
      */
     @Override
-    protected Method doFindMethod( final Class<?> targetClass,
+    protected MethodInfo<List<ParamType>> doFindMethod(final Class<?> targetClass,
     		final boolean acceptPrivate,
     		final boolean acceptPackage,
     		final SimpleLogger logger )
@@ -119,8 +119,8 @@ implements org.apache.felix.scr.impl.hel
                 {
                     logger.log( LogService.LOG_DEBUG, "doFindMethod: Found Method " + method, null );
                 }
-                m_paramTypes = Collections.singletonList(ParamType.serviceReference);
-                return method;
+                return new MethodInfo<List<ParamType>>(method,
+                    Collections.singletonList(ParamType.serviceReference));
             }
         }
         catch ( SuitableMethodNotAccessibleException ex )
@@ -140,8 +140,8 @@ implements org.apache.felix.scr.impl.hel
 	                {
 	                    logger.log( LogService.LOG_DEBUG, "doFindMethod: Found Method " + method, null );
 	                }
-	                m_paramTypes = Collections.singletonList(ParamType.serviceObjects);
-	                return method;
+                    return new MethodInfo<List<ParamType>>(method,
+                        Collections.singletonList(ParamType.serviceObjects));
 	            }
 	        }
 	        catch ( SuitableMethodNotAccessibleException ex )
@@ -173,8 +173,8 @@ implements org.apache.felix.scr.impl.hel
 	                {
 	                    logger.log( LogService.LOG_DEBUG, "doFindMethod: Found Method " + method, null );
 	                }
-	                m_paramTypes = Collections.singletonList(ParamType.serviceType);
-                    return method;
+                    return new MethodInfo<List<ParamType>>(method,
+                        Collections.singletonList(ParamType.serviceType));
                 }
             }
             catch ( SuitableMethodNotAccessibleException ex )
@@ -192,8 +192,8 @@ implements org.apache.felix.scr.impl.hel
 	                {
 	                    logger.log( LogService.LOG_DEBUG, "doFindMethod: Found Method " + method, null );
 	                }
-                    m_paramTypes = Collections.singletonList(ParamType.serviceType);
-                    return method;
+                    return new MethodInfo<List<ParamType>>(method,
+                        Collections.singletonList(ParamType.serviceType));
                 }
             }
             catch ( SuitableMethodNotAccessibleException ex )
@@ -213,8 +213,8 @@ implements org.apache.felix.scr.impl.hel
     	                {
     	                    logger.log( LogService.LOG_DEBUG, "doFindMethod: Found Method " + method, null );
     	                }
-                        m_paramTypes = Collections.singletonList(ParamType.map);
-                        return method;
+                        return new MethodInfo<List<ParamType>>(method,
+                            Collections.singletonList(ParamType.map));
                     }
                 }
                 catch ( SuitableMethodNotAccessibleException ex )
@@ -240,8 +240,7 @@ implements org.apache.felix.scr.impl.hel
                         List<ParamType> paramTypes = new ArrayList<ParamType>(2);
                         paramTypes.add(ParamType.serviceType);
                         paramTypes.add(ParamType.map);
-                        m_paramTypes = paramTypes;
-                        return method;
+                        return new MethodInfo<List<ParamType>>(method, paramTypes);
                     }
                 }
                 catch ( SuitableMethodNotAccessibleException ex )
@@ -263,8 +262,7 @@ implements org.apache.felix.scr.impl.hel
                         List<ParamType> paramTypes = new ArrayList<ParamType>(2);
                         paramTypes.add(ParamType.serviceType);
                         paramTypes.add(ParamType.map);
-                        m_paramTypes = paramTypes;
-                        return method;
+                        return new MethodInfo<List<ParamType>>(method, paramTypes);
                     }
                 }
                 catch ( SuitableMethodNotAccessibleException ex )
@@ -338,8 +336,7 @@ implements org.apache.felix.scr.impl.hel
             	                {
             	                    logger.log( LogService.LOG_DEBUG, "doFindMethod: Found Method " + m, null );
             	                }
-                                m_paramTypes = paramTypes;
-                                return m;
+                                return new MethodInfo<List<ParamType>>(m, paramTypes);
                             }
                             suitableMethodNotAccessible = true;
                         }
@@ -369,6 +366,12 @@ implements org.apache.felix.scr.impl.hel
         return null;
     }
 
+    @Override
+    protected void setTypes(List<ParamType> types)
+    {
+        m_paramTypes = types;
+    }
+
     /**
      * Returns a method taking a single <code>ServiceReference</code> object
      * as a parameter or <code>null</code> if no such method exists.