Skip to content

Commit

Permalink
fix(android): prevent headless task double-invocation
Browse files Browse the repository at this point in the history
it was possible if multiple tasks came in at once while react-native
headlessJS was performing initial react-native startup for the queued
events to be invoked multiple times once startup finished

this is protected via a couple mechanisms now
  • Loading branch information
mikehardy committed Dec 20, 2024
1 parent 451900c commit a799167
Showing 1 changed file with 16 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ static synchronized int getNextTaskId() {

private final List<TaskConfig> mTaskQueue = new ArrayList<>();
private final AtomicBoolean mIsReactContextInitialized = new AtomicBoolean(false);
private final AtomicBoolean mWillDrainTaskQueue = new AtomicBoolean(false);
private final AtomicBoolean mIsInitializingReactContext = new AtomicBoolean(false);
private final AtomicBoolean mIsHeadlessJsTaskListenerRegistered = new AtomicBoolean(false);

Expand Down Expand Up @@ -184,6 +185,10 @@ public void startTask(Context context, final TaskConfig taskConfig) throws Asser

private synchronized void invokeStartTask(
ReactContext reactContext, final TaskConfig taskConfig) {
if (taskConfig.mReactTaskId > 0) {
Log.w(HEADLESS_TASK_NAME, "Task already invoked <IGNORED>: " + this);
return;
}
final HeadlessJsTaskContext headlessJsTaskContext =
HeadlessJsTaskContext.getInstance(reactContext);
try {
Expand Down Expand Up @@ -339,16 +344,18 @@ public void onReactContextInitialized(@NonNull ReactContext reactContext) {
* @param reactContext
*/
private void drainTaskQueue(final ReactContext reactContext) {
new Handler(Looper.getMainLooper())
.postDelayed(
() -> {
synchronized (mTaskQueue) {
for (TaskConfig taskConfig : mTaskQueue) {
invokeStartTask(reactContext, taskConfig);
if (mWillDrainTaskQueue.compareAndSet(false, true)) {
new Handler(Looper.getMainLooper())
.postDelayed(
() -> {
synchronized (mTaskQueue) {
for (TaskConfig taskConfig : mTaskQueue) {
invokeStartTask(reactContext, taskConfig);
}
}
}
},
500);
},
500);
}
}

/**
Expand Down

0 comments on commit a799167

Please sign in to comment.