Skip to content

Commit

Permalink
Fix DynamicFromMap object pool synchronization (facebook#17842)
Browse files Browse the repository at this point in the history
Summary:
DynamicFromMap internally uses SimplePool object to recycle dynamic prop objects. But the pool is not multi-thread safe. Currently the most used dynamic props are size props such as left, paddingVertical, marginTop and so on. These props are only accessed from the layout thread so the pool works fine. If a dynamic prop is needed in UI thread, then the two threads can access the same pool object and cause random errors. This PR make the pool object thread local to avoid synchronization. After this change there are two pool objects created in the process.

Tested in official Airbnb app after updating accessibilityComponentType to be dynamic.

Once this is merged, I'll send another PR to support "disabled" state in `accessibilityComponentType`.

[ANDROID] [BUGFIX] [DynamicFromMap] - Fix a crash caused by dynamic props.
Pull Request resolved: facebook#17842

Differential Revision: D10374238

Pulled By: hramos

fbshipit-source-id: 7ebf89c5abf06bd5fb43b205348ba4dc7e19517d
  • Loading branch information
haitaoli authored and sjchmiela committed Oct 24, 2018
1 parent 5345d7b commit 6fa8703
Showing 1 changed file with 9 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,18 @@

import javax.annotation.Nullable;

import android.support.v4.util.Pools;
import android.support.v4.util.Pools.SimplePool;

/**
* Implementation of Dynamic wrapping a ReadableMap.
*/
public class DynamicFromMap implements Dynamic {
private static final Pools.SimplePool<DynamicFromMap> sPool = new Pools.SimplePool<>(10);
private static final ThreadLocal<SimplePool<DynamicFromMap>> sPool = new ThreadLocal<SimplePool<DynamicFromMap>>() {
@Override
protected SimplePool<DynamicFromMap> initialValue() {
return new SimplePool<>(10);
}
};

private @Nullable ReadableMap mMap;
private @Nullable String mName;
Expand All @@ -24,7 +29,7 @@ public class DynamicFromMap implements Dynamic {
private DynamicFromMap() {}

public static DynamicFromMap create(ReadableMap map, String name) {
DynamicFromMap dynamic = sPool.acquire();
DynamicFromMap dynamic = sPool.get().acquire();
if (dynamic == null) {
dynamic = new DynamicFromMap();
}
Expand All @@ -37,7 +42,7 @@ public static DynamicFromMap create(ReadableMap map, String name) {
public void recycle() {
mMap = null;
mName = null;
sPool.release(this);
sPool.get().release(this);
}

@Override
Expand Down

0 comments on commit 6fa8703

Please sign in to comment.