This is an automated email from the ASF dual-hosted git repository.

tjwatson pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/felix-dev.git


The following commit(s) were added to refs/heads/master by this push:
     new cf2cf3c  Introduced thread-safety while updating field during 
deactivation phase
     new 6695a8a  Merge pull request #81 from amitjoy/bug/FELIX-6439/npe-treemap
cf2cf3c is described below

commit cf2cf3c57801944650ca846f452adf0b0d3755da
Author: Amit Kumar Mondal <[email protected]>
AuthorDate: Thu Jul 22 14:46:07 2021 +0200

    Introduced thread-safety while updating field during deactivation phase
    
    The problem occurred when multiple injected services tried to be removed 
from the component's injection. It is highly likely because of the usage of 
TreeMap in such concurrent environment. Since TreeMap has never been written to 
be used in a concurrent environment, we should use ConcurrentSkipListMap 
instead as all the features of TreeMap have been introduced in 
ConcurrentSkipListMap and it is very much suitable for concurrent environment.
    Introduced thread-safety while updating field during deactivation phase
---
 .../apache/felix/scr/impl/inject/field/FieldHandler.java | 16 ++++++++++------
 .../felix/scr/impl/manager/ComponentContextImpl.java     | 13 ++-----------
 2 files changed, 12 insertions(+), 17 deletions(-)

diff --git 
a/scr/src/main/java/org/apache/felix/scr/impl/inject/field/FieldHandler.java 
b/scr/src/main/java/org/apache/felix/scr/impl/inject/field/FieldHandler.java
index 49f4964..541e88b 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/inject/field/FieldHandler.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/inject/field/FieldHandler.java
@@ -25,6 +25,7 @@ import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.CopyOnWriteArraySet;
 
@@ -42,7 +43,6 @@ import org.apache.felix.scr.impl.logger.ComponentLogger;
 import org.apache.felix.scr.impl.logger.InternalLogger.Level;
 import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
 import org.osgi.framework.BundleContext;
-import org.osgi.service.log.LogLevel;
 
 /**
  * Handler for field references
@@ -186,15 +186,19 @@ public class FieldHandler
                // unbind needs only be done, if reference is dynamic and 
optional
             if ( mType == METHOD_TYPE.UNBIND )
             {
-                if ( this.metadata.isOptional() && !this.metadata.isStatic() )
+                Map<RefPair<?, ?>, Object> boundValues = 
bp.getComponentContext().getBoundValues(metadata.getName());
+                synchronized (boundValues) 
                 {
-                    // we only reset if it was previously set with this value
-                    if ( 
bp.getComponentContext().getBoundValues(metadata.getName()).size() == 1 )
+                    if ( this.metadata.isOptional() && 
!this.metadata.isStatic() )
                     {
-                        this.setFieldValue(componentInstance, null);
+                        // we only reset if it was previously set with this 
value
+                        if ( boundValues.size() == 1 )
+                        {
+                            this.setFieldValue(componentInstance, null);
+                        }
                     }
+                    boundValues.remove(refPair);
                 }
-                
bp.getComponentContext().getBoundValues(metadata.getName()).remove(refPair);
             }
             // updated needs only be done, if the value type is map or tuple
             // If it's a dynamic reference, the value can be updated
diff --git 
a/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java 
b/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java
index 3204e18..faaa498 100644
--- 
a/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java
+++ 
b/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java
@@ -19,7 +19,7 @@
 package org.apache.felix.scr.impl.manager;
 
 
-import java.util.Comparator;
+import java.util.Collections;
 import java.util.Dictionary;
 import java.util.HashMap;
 import java.util.Map;
@@ -328,15 +328,6 @@ public class ComponentContextImpl<S> implements 
ScrComponentContext {
 
     private Map<RefPair<?, ?>, Object> createNewFieldHandlerMap()
     {
-        return new TreeMap<>(
-            new Comparator<RefPair<?, ?>>()
-            {
-
-                @Override
-                public int compare(final RefPair<?, ?> o1, final RefPair<?, ?> 
o2)
-                {
-                    return o1.getRef().compareTo(o2.getRef());
-                }
-            });
+        return Collections.synchronizedMap(new TreeMap<>((o1, o2) -> 
o1.getRef().compareTo(o2.getRef())));
     }
 }

Reply via email to