Skip to content

nil #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed

nil #1

wants to merge 1 commit into from

Conversation

robz
Copy link

@robz robz commented Jan 28, 2015

No description provided.

@sophiebits sophiebits changed the title fixed readme step orderding nil Jan 29, 2015
@sophiebits sophiebits closed this Jan 29, 2015
@sophiebits sophiebits deleted the patch-1 branch January 29, 2015 22:08
harrykiselev pushed a commit to harrykiselev/react-native that referenced this pull request Aug 5, 2015
Explain how to open the chat example
ide referenced this pull request in expo/react-native Sep 15, 2015
add react-native android command (wip)
brentvatne pushed a commit that referenced this pull request Nov 9, 2015
chirag04 pushed a commit that referenced this pull request Jan 25, 2016
ekrivopaltsev pushed a commit to ekrivopaltsev/react-native that referenced this pull request Mar 25, 2016
Some keyboard types does not have buttons correspondent for keyReturnType such as Next, Done. It is observable on IPhone for numeric keyboard types. That prevents traversing forms with "number" input fields and impacts end-user experience.

The improvement allows application for adding extra buttons via inputAccessoryView.
Because RCTText is not a project exposed to React application calling all methods to add a handler is done using selectors.

Here is a code fragment which has an example on how to achieve it:
Within application:
facebook#1 Create a keyboard Handle
 KeyboardAccessory keyboardHandler = ^UIView *(UITextField *textField) {
    ReactTextAdapter *kAdapter = [[ReactTextAdapter alloc] init:textField];
    return [kAdapter getInputAccessory];
  };

2. Register an adapter

  Class clz = NSClassFromString(@"RCTTextField");

  SEL selector = NSSelectorFromString(@"registerForKeyboardType:handler:");
  if ([clz respondsToSelector:selector]) {
  [   clz performSelector:selector withObject:[NSNumber numberWithInt:UIKeyboardTypeNumberPad] withObject:keyboardHandler];
  }

facebook#3 Example of Keyboard Adapter

@interface ReactTextAdapter :UIToolbar

-(instancetype) init:(UITextField *)textField;
-(UIView *)getInputAccessory;

@EnD

//
//  ReactTextAdapter.m
//  KeyboardTest
//
//  Created by Krivopaltsev, Eugene on 3/11/16.
//

#import "ReactTextAdapter.h"

@interface ReactTextAdapter()

@Property (nonatomic) UITextField *textField;

//@Property (nonatomic)UIToolbar *toolBar;
@Property (nonatomic)UIBarButtonItem *flexible;

@EnD

@implementation ReactTextAdapter

-(instancetype) init:(UITextField *)textField {
  self = [super init];
  if (self) {
    self.textField = textField;

    [self setBarStyle:UIBarStyleDefault];
    self.translatesAutoresizingMaskIntoConstraints = NO;
    self.flexible = [[UIBarButtonItem alloc]
                     initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
                     target:self action:nil];

    // since there is a next field, add a NEXT button to the picker
    if (self. textField. returnKeyType == UIReturnKeyNext) {
      NSString *nextText = @"Next";
      UIBarButtonItem *nextButton = [[UIBarButtonItem alloc] initWithTitle:nextText
                                                                   style:UIBarButtonItemStyleDone
                                                                  target:self
                                                                  action:@selector(next)];

      self.items = [[NSArray alloc] initWithObjects: self.flexible, nextButton, nil];
    }else if (self.textField. returnKeyType == UIReturnKeyContinue) {

      NSString *continueText = @"Continue";
      UIBarButtonItem *contButton = [[UIBarButtonItem alloc] initWithTitle:continueText
                                                                     style:UIBarButtonItemStyleDone
                                                                    target:self
                                                                    action:@selector(next)];

      self.items = [[NSArray alloc] initWithObjects: self.flexible, contButton, nil];
    }
    else if (self. textField.returnKeyType == UIReturnKeyDone) {

      NSString *doneText = @"Done";
      UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:doneText
                                                                     style:UIBarButtonItemStyleDone
                                                                    target:self
                                                                    action:@selector(done)];
      doneButton.enabled = YES;

      self.items = [[NSArray alloc] initWithObjects: self.flexible, doneButton, nil];
    }

  }
  return self;
}
-(void) done {
  [self passToReactNative];
  [self.textField resignFirstResponder];
}

-(void) next {
  [self passToReactNative];
}

-(void) passToReactNative {
  SEL selector = @selector(textFieldSubmitEditing);
  if ([self.textField respondsToSelector:selector]) {
    [self.textField performSelector:selector withObject:nil];
  }
}

-(UIView *)getInputAccessory {
  return self;
}
ekrivopaltsev pushed a commit to ekrivopaltsev/react-native that referenced this pull request Mar 25, 2016
Some keyboard types does not have buttons correspondent for keyReturnType such as Next, Done. It is observable on IPhone for numeric keyboard types. That prevents traversing forms with "number" input fields and impacts end-user experience.

The improvement allows application for adding extra buttons via inputAccessoryView.
Because RCTText is not a project exposed to React application calling all methods to add a handler is done using selectors.

Here is a code fragment which has an example on how to achieve it:
Within application:
facebook#1 Create a keyboard Handle
 KeyboardAccessory keyboardHandler = ^UIView *(UITextField *textField) {
    ReactTextAdapter *kAdapter = [[ReactTextAdapter alloc] init:textField];
    return [kAdapter getInputAccessory];
  };

2. Register an adapter

  Class clz = NSClassFromString(@"RCTTextField");

  SEL selector = NSSelectorFromString(@"registerForKeyboardType:handler:");
  if ([clz respondsToSelector:selector]) {
  [   clz performSelector:selector withObject:[NSNumber numberWithInt:UIKeyboardTypeNumberPad] withObject:keyboardHandler];
  }

facebook#3 Example of Keyboard Adapter

@interface ReactTextAdapter :UIToolbar

-(instancetype) init:(UITextField *)textField;
-(UIView *)getInputAccessory;

@EnD

//
//  ReactTextAdapter.m
//  KeyboardTest
//
//  Created by Krivopaltsev, Eugene on 3/11/16.
//

#import "ReactTextAdapter.h"

@interface ReactTextAdapter()

@Property (nonatomic) UITextField *textField;

//@Property (nonatomic)UIToolbar *toolBar;
@Property (nonatomic)UIBarButtonItem *flexible;

@EnD

@implementation ReactTextAdapter

-(instancetype) init:(UITextField *)textField {
  self = [super init];
  if (self) {
    self.textField = textField;

    [self setBarStyle:UIBarStyleDefault];
    self.translatesAutoresizingMaskIntoConstraints = NO;
    self.flexible = [[UIBarButtonItem alloc]
                     initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
                     target:self action:nil];

    // since there is a next field, add a NEXT button to the picker
    if (self. textField. returnKeyType == UIReturnKeyNext) {
      NSString *nextText = @"Next";
      UIBarButtonItem *nextButton = [[UIBarButtonItem alloc] initWithTitle:nextText
                                                                   style:UIBarButtonItemStyleDone
                                                                  target:self
                                                                  action:@selector(next)];

      self.items = [[NSArray alloc] initWithObjects: self.flexible, nextButton, nil];
    }else if (self.textField. returnKeyType == UIReturnKeyContinue) {

      NSString *continueText = @"Continue";
      UIBarButtonItem *contButton = [[UIBarButtonItem alloc] initWithTitle:continueText
                                                                     style:UIBarButtonItemStyleDone
                                                                    target:self
                                                                    action:@selector(next)];

      self.items = [[NSArray alloc] initWithObjects: self.flexible, contButton, nil];
    }
    else if (self. textField.returnKeyType == UIReturnKeyDone) {

      NSString *doneText = @"Done";
      UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:doneText
                                                                     style:UIBarButtonItemStyleDone
                                                                    target:self
                                                                    action:@selector(done)];
      doneButton.enabled = YES;

      self.items = [[NSArray alloc] initWithObjects: self.flexible, doneButton, nil];
    }

  }
  return self;
}
-(void) done {
  [self passToReactNative];
  [self.textField resignFirstResponder];
}

-(void) next {
  [self passToReactNative];
}

-(void) passToReactNative {
  SEL selector = @selector(textFieldSubmitEditing);
  if ([self.textField respondsToSelector:selector]) {
    [self.textField performSelector:selector withObject:nil];
  }
}

-(UIView *)getInputAccessory {
  return self;
}
@facebook-github-bot
Copy link
Contributor

@robz updated the pull request.

RSNara added a commit to RSNara/react-native that referenced this pull request May 23, 2025
Summary:
Pull Request resolved: facebook#51425

# Problem

React native's new architecture will allow components to do sync render/events. That means they'll makes synchronous dispatches from main thread to the js thread, to capture the runtime so that they can execute js on the main thread.

But, the js thread already as a bunch of synchronous calls to the main thread. So, if any of those js -> ui sync calls happen concurrently with a synchronous render, the application will deadlock.

This diff is an attempt to mitigate all those deadlocks.

## Context
How js execution from the main thread works:

* Main thread puts a block on the js thread, to capture the js runtime. Main thread is put to sleep.
* Js thread executes "runtime capture block". The runtime is captured for the main thread. The js thread is put to sleep.
* Main thread wakes up, noticing that the runtime is captured. It executes its js code with the captured runtime. Then, it releases the runtime, which wakes up the js thread. Both the main and js thread move on to other tasks.

How synchronous js -> main thread calls work:
* Js thread puts a ui block on the main queue.
* Js thread goes to sleep until that ui block executes on the main thread.

## Deadlock facebook#1
**Main thread**: execute js now:
  * Main thread puts a block on the js queue, to capture the runtime.
 * Main thread then then goes to sleep, waiting for runtime to be captured

**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep, waiting for that block to execute.

**Result:** The application deadlocks

| {F1978009555} |  {F1978009612} |

![image](https://github.com/user-attachments/assets/325a62f4-d5b7-492d-a114-efb738556239)

## Deadlock facebook#2
**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep waiting for that block to execute.

**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime to be captured

**Result:** The application deadlocks

|  {F1978009690}  | {F1978009701} |

![image](https://github.com/user-attachments/assets/13a6ea17-a55d-453d-9291-d1c8007ecffa)

# Changes
This diff attempts to fix those deadlocks. How:
* In "execute ui code synchronously" (js thread):
   * Before going to sleep, the js thread schedules the ui work on the main queue, **and** it  posts the ui work to "execute js now".
* In "execute js now" (main thread):
   * This diff makes "execute js now" stateful: it keeps a "pending ui block."
   * Before capturing the runtime, the "execute js now" executes "pending ui work", if it exists.
   * While sleeping waiting for runtime capture, "execute js now" can wake up, and execute "pending ui work." It goes back to sleep afterwards, waiting for runtime capture.

## Mitigation: Deadlock facebook#1
**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime capture

**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

The main thread wakes up in "execute js now":
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block." The block, also scheduled on the main thread, noops henceforth.
* Main thread goes back to sleep, waiting for runtime capture.
* The js thread wakes up, moves on to the next task.

**Result:** The runtime is captured by the main thread.

| {F1978010383} | {F1978010363} |  {F1978010371} |  {F1978010379} |

![image](https://github.com/user-attachments/assets/f53cb10c-7801-46be-934a-96af7d5f5fab)

## Mitigation: Deadlock facebook#2
**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

**Main thread**: execute js now
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block" immediately. The block, also scheduled on the main thread, noops henceforth.
* Js thread wakes up and moves onto the next task.

**Result:** Main thread captures the runtime.

|  {F1978010525}  |  {F1978010533} |  {F1978010542} |

![image](https://github.com/user-attachments/assets/9e0ca5ef-fab6-4a26-bcca-d79d36624d5d)

Differential Revision: D74769326
RSNara added a commit to RSNara/react-native that referenced this pull request May 23, 2025
Summary:
Pull Request resolved: facebook#51425

# Problem

React native's new architecture will allow components to do sync render/events. That means they'll makes synchronous dispatches from main thread to the js thread, to capture the runtime so that they can execute js on the main thread.

But, the js thread already as a bunch of synchronous calls to the main thread. So, if any of those js -> ui sync calls happen concurrently with a synchronous render, the application will deadlock.

This diff is an attempt to mitigate all those deadlocks.

## Context
How js execution from the main thread works:

* Main thread puts a block on the js thread, to capture the js runtime. Main thread is put to sleep.
* Js thread executes "runtime capture block". The runtime is captured for the main thread. The js thread is put to sleep.
* Main thread wakes up, noticing that the runtime is captured. It executes its js code with the captured runtime. Then, it releases the runtime, which wakes up the js thread. Both the main and js thread move on to other tasks.

How synchronous js -> main thread calls work:
* Js thread puts a ui block on the main queue.
* Js thread goes to sleep until that ui block executes on the main thread.

## Deadlock facebook#1
**Main thread**: execute js now:
  * Main thread puts a block on the js queue, to capture the runtime.
 * Main thread then then goes to sleep, waiting for runtime to be captured

**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep, waiting for that block to execute.

**Result:** The application deadlocks

| {F1978009555} |  {F1978009612} |

![image](https://github.com/user-attachments/assets/325a62f4-d5b7-492d-a114-efb738556239)

## Deadlock facebook#2
**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep waiting for that block to execute.

**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime to be captured

**Result:** The application deadlocks

|  {F1978009690}  | {F1978009701} |

![image](https://github.com/user-attachments/assets/13a6ea17-a55d-453d-9291-d1c8007ecffa)

# Changes
This diff attempts to fix those deadlocks. How:
* In "execute ui code synchronously" (js thread):
   * Before going to sleep, the js thread schedules the ui work on the main queue, **and** it  posts the ui work to "execute js now".
* In "execute js now" (main thread):
   * This diff makes "execute js now" stateful: it keeps a "pending ui block."
   * Before capturing the runtime, the "execute js now" executes "pending ui work", if it exists.
   * While sleeping waiting for runtime capture, "execute js now" can wake up, and execute "pending ui work." It goes back to sleep afterwards, waiting for runtime capture.

## Mitigation: Deadlock facebook#1
**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime capture

**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

The main thread wakes up in "execute js now":
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block." The block, also scheduled on the main thread, noops henceforth.
* Main thread goes back to sleep, waiting for runtime capture.
* The js thread wakes up, moves on to the next task.

**Result:** The runtime is captured by the main thread.

| {F1978010383} | {F1978010363} |  {F1978010371} |  {F1978010379} |

![image](https://github.com/user-attachments/assets/f53cb10c-7801-46be-934a-96af7d5f5fab)

## Mitigation: Deadlock facebook#2
**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

**Main thread**: execute js now
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block" immediately. The block, also scheduled on the main thread, noops henceforth.
* Js thread wakes up and moves onto the next task.

**Result:** Main thread captures the runtime.

|  {F1978010525}  |  {F1978010533} |  {F1978010542} |

![image](https://github.com/user-attachments/assets/9e0ca5ef-fab6-4a26-bcca-d79d36624d5d)

Differential Revision: D74769326
RSNara added a commit to RSNara/react-native that referenced this pull request May 23, 2025
Summary:
Pull Request resolved: facebook#51425

# Problem

React native's new architecture will allow components to do sync render/events. That means they'll makes synchronous dispatches from main thread to the js thread, to capture the runtime so that they can execute js on the main thread.

But, the js thread already as a bunch of synchronous calls to the main thread. So, if any of those js -> ui sync calls happen concurrently with a synchronous render, the application will deadlock.

This diff is an attempt to mitigate all those deadlocks.

## Context
How js execution from the main thread works:

* Main thread puts a block on the js thread, to capture the js runtime. Main thread is put to sleep.
* Js thread executes "runtime capture block". The runtime is captured for the main thread. The js thread is put to sleep.
* Main thread wakes up, noticing that the runtime is captured. It executes its js code with the captured runtime. Then, it releases the runtime, which wakes up the js thread. Both the main and js thread move on to other tasks.

How synchronous js -> main thread calls work:
* Js thread puts a ui block on the main queue.
* Js thread goes to sleep until that ui block executes on the main thread.

## Deadlock facebook#1
**Main thread**: execute js now:
  * Main thread puts a block on the js queue, to capture the runtime.
 * Main thread then then goes to sleep, waiting for runtime to be captured

**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep, waiting for that block to execute.

**Result:** The application deadlocks

| {F1978009555} |  {F1978009612} |

![image](https://github.com/user-attachments/assets/325a62f4-d5b7-492d-a114-efb738556239)

## Deadlock facebook#2
**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep waiting for that block to execute.

**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime to be captured

**Result:** The application deadlocks

|  {F1978009690}  | {F1978009701} |

![image](https://github.com/user-attachments/assets/13a6ea17-a55d-453d-9291-d1c8007ecffa)

# Changes
This diff attempts to fix those deadlocks. How:
* In "execute ui code synchronously" (js thread):
   * Before going to sleep, the js thread schedules the ui work on the main queue, **and** it  posts the ui work to "execute js now".
* In "execute js now" (main thread):
   * This diff makes "execute js now" stateful: it keeps a "pending ui block."
   * Before capturing the runtime, the "execute js now" executes "pending ui work", if it exists.
   * While sleeping waiting for runtime capture, "execute js now" can wake up, and execute "pending ui work." It goes back to sleep afterwards, waiting for runtime capture.

## Mitigation: Deadlock facebook#1
**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime capture

**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

The main thread wakes up in "execute js now":
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block." The block, also scheduled on the main thread, noops henceforth.
* Main thread goes back to sleep, waiting for runtime capture.
* The js thread wakes up, moves on to the next task.

**Result:** The runtime is captured by the main thread.

| {F1978010383} | {F1978010363} |  {F1978010371} |  {F1978010379} |

![image](https://github.com/user-attachments/assets/f53cb10c-7801-46be-934a-96af7d5f5fab)

## Mitigation: Deadlock facebook#2
**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

**Main thread**: execute js now
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block" immediately. The block, also scheduled on the main thread, noops henceforth.
* Js thread wakes up and moves onto the next task.

**Result:** Main thread captures the runtime.

|  {F1978010525}  |  {F1978010533} |  {F1978010542} |

![image](https://github.com/user-attachments/assets/9e0ca5ef-fab6-4a26-bcca-d79d36624d5d)

Differential Revision: D74769326
RSNara added a commit to RSNara/react-native that referenced this pull request May 23, 2025
Summary:
Pull Request resolved: facebook#51425

# Problem

React native's new architecture will allow components to do sync render/events. That means they'll makes synchronous dispatches from main thread to the js thread, to capture the runtime so that they can execute js on the main thread.

But, the js thread already as a bunch of synchronous calls to the main thread. So, if any of those js -> ui sync calls happen concurrently with a synchronous render, the application will deadlock.

This diff is an attempt to mitigate all those deadlocks.

## Context
How js execution from the main thread works:

* Main thread puts a block on the js thread, to capture the js runtime. Main thread is put to sleep.
* Js thread executes "runtime capture block". The runtime is captured for the main thread. The js thread is put to sleep.
* Main thread wakes up, noticing that the runtime is captured. It executes its js code with the captured runtime. Then, it releases the runtime, which wakes up the js thread. Both the main and js thread move on to other tasks.

How synchronous js -> main thread calls work:
* Js thread puts a ui block on the main queue.
* Js thread goes to sleep until that ui block executes on the main thread.

## Deadlock facebook#1
**Main thread**: execute js now:
  * Main thread puts a block on the js queue, to capture the runtime.
 * Main thread then then goes to sleep, waiting for runtime to be captured

**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep, waiting for that block to execute.

**Result:** The application deadlocks

| {F1978009555} |  {F1978009612} |

![image](https://github.com/user-attachments/assets/325a62f4-d5b7-492d-a114-efb738556239)

## Deadlock facebook#2
**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep waiting for that block to execute.

**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime to be captured

**Result:** The application deadlocks

|  {F1978009690}  | {F1978009701} |

![image](https://github.com/user-attachments/assets/13a6ea17-a55d-453d-9291-d1c8007ecffa)

# Changes
This diff attempts to fix those deadlocks. How:
* In "execute ui code synchronously" (js thread):
   * Before going to sleep, the js thread schedules the ui work on the main queue, **and** it  posts the ui work to "execute js now".
* In "execute js now" (main thread):
   * This diff makes "execute js now" stateful: it keeps a "pending ui block."
   * Before capturing the runtime, the "execute js now" executes "pending ui work", if it exists.
   * While sleeping waiting for runtime capture, "execute js now" can wake up, and execute "pending ui work." It goes back to sleep afterwards, waiting for runtime capture.

## Mitigation: Deadlock facebook#1
**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime capture

**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

The main thread wakes up in "execute js now":
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block." The block, also scheduled on the main thread, noops henceforth.
* Main thread goes back to sleep, waiting for runtime capture.
* The js thread wakes up, moves on to the next task.

**Result:** The runtime is captured by the main thread.

| {F1978010383} | {F1978010363} |  {F1978010371} |  {F1978010379} |

![image](https://github.com/user-attachments/assets/f53cb10c-7801-46be-934a-96af7d5f5fab)

## Mitigation: Deadlock facebook#2
**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

**Main thread**: execute js now
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block" immediately. The block, also scheduled on the main thread, noops henceforth.
* Js thread wakes up and moves onto the next task.

**Result:** Main thread captures the runtime.

|  {F1978010525}  |  {F1978010533} |  {F1978010542} |

![image](https://github.com/user-attachments/assets/9e0ca5ef-fab6-4a26-bcca-d79d36624d5d)

Differential Revision: D74769326
RSNara added a commit to RSNara/react-native that referenced this pull request May 23, 2025
Summary:
Pull Request resolved: facebook#51425

# Problem

React native's new architecture will allow components to do sync render/events. That means they'll makes synchronous dispatches from main thread to the js thread, to capture the runtime so that they can execute js on the main thread.

But, the js thread already as a bunch of synchronous calls to the main thread. So, if any of those js -> ui sync calls happen concurrently with a synchronous render, the application will deadlock.

This diff is an attempt to mitigate all those deadlocks.

## Context
How js execution from the main thread works:

* Main thread puts a block on the js thread, to capture the js runtime. Main thread is put to sleep.
* Js thread executes "runtime capture block". The runtime is captured for the main thread. The js thread is put to sleep.
* Main thread wakes up, noticing that the runtime is captured. It executes its js code with the captured runtime. Then, it releases the runtime, which wakes up the js thread. Both the main and js thread move on to other tasks.

How synchronous js -> main thread calls work:
* Js thread puts a ui block on the main queue.
* Js thread goes to sleep until that ui block executes on the main thread.

## Deadlock facebook#1
**Main thread**: execute js now:
  * Main thread puts a block on the js queue, to capture the runtime.
 * Main thread then then goes to sleep, waiting for runtime to be captured

**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep, waiting for that block to execute.

**Result:** The application deadlocks

| {F1978009555} |  {F1978009612} |

![image](https://github.com/user-attachments/assets/325a62f4-d5b7-492d-a114-efb738556239)

## Deadlock facebook#2
**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep waiting for that block to execute.

**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime to be captured

**Result:** The application deadlocks

|  {F1978009690}  | {F1978009701} |

![image](https://github.com/user-attachments/assets/13a6ea17-a55d-453d-9291-d1c8007ecffa)

# Changes
This diff attempts to fix those deadlocks. How:
* In "execute ui code synchronously" (js thread):
   * Before going to sleep, the js thread schedules the ui work on the main queue, **and** it  posts the ui work to "execute js now".
* In "execute js now" (main thread):
   * This diff makes "execute js now" stateful: it keeps a "pending ui block."
   * Before capturing the runtime, the "execute js now" executes "pending ui work", if it exists.
   * While sleeping waiting for runtime capture, "execute js now" can wake up, and execute "pending ui work." It goes back to sleep afterwards, waiting for runtime capture.

## Mitigation: Deadlock facebook#1
**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime capture

**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

The main thread wakes up in "execute js now":
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block." The block, also scheduled on the main thread, noops henceforth.
* Main thread goes back to sleep, waiting for runtime capture.
* The js thread wakes up, moves on to the next task.

**Result:** The runtime is captured by the main thread.

| {F1978010383} | {F1978010363} |  {F1978010371} |  {F1978010379} |

![image](https://github.com/user-attachments/assets/f53cb10c-7801-46be-934a-96af7d5f5fab)

## Mitigation: Deadlock facebook#2
**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

**Main thread**: execute js now
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block" immediately. The block, also scheduled on the main thread, noops henceforth.
* Js thread wakes up and moves onto the next task.

**Result:** Main thread captures the runtime.

|  {F1978010525}  |  {F1978010533} |  {F1978010542} |

![image](https://github.com/user-attachments/assets/9e0ca5ef-fab6-4a26-bcca-d79d36624d5d)

Differential Revision: D74769326
RSNara added a commit to RSNara/react-native that referenced this pull request May 23, 2025
Summary:
Pull Request resolved: facebook#51425

# Problem

React native's new architecture will allow components to do sync render/events. That means they'll makes synchronous dispatches from main thread to the js thread, to capture the runtime so that they can execute js on the main thread.

But, the js thread already as a bunch of synchronous calls to the main thread. So, if any of those js -> ui sync calls happen concurrently with a synchronous render, the application will deadlock.

This diff is an attempt to mitigate all those deadlocks.

## Context
How js execution from the main thread works:

* Main thread puts a block on the js thread, to capture the js runtime. Main thread is put to sleep.
* Js thread executes "runtime capture block". The runtime is captured for the main thread. The js thread is put to sleep.
* Main thread wakes up, noticing that the runtime is captured. It executes its js code with the captured runtime. Then, it releases the runtime, which wakes up the js thread. Both the main and js thread move on to other tasks.

How synchronous js -> main thread calls work:
* Js thread puts a ui block on the main queue.
* Js thread goes to sleep until that ui block executes on the main thread.

## Deadlock facebook#1
**Main thread**: execute js now:
  * Main thread puts a block on the js queue, to capture the runtime.
 * Main thread then then goes to sleep, waiting for runtime to be captured

**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep, waiting for that block to execute.

**Result:** The application deadlocks

| {F1978009555} |  {F1978009612} |

![image](https://github.com/user-attachments/assets/325a62f4-d5b7-492d-a114-efb738556239)

## Deadlock facebook#2
**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep waiting for that block to execute.

**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime to be captured

**Result:** The application deadlocks

|  {F1978009690}  | {F1978009701} |

![image](https://github.com/user-attachments/assets/13a6ea17-a55d-453d-9291-d1c8007ecffa)

# Changes
This diff attempts to fix those deadlocks. How:
* In "execute ui code synchronously" (js thread):
   * Before going to sleep, the js thread schedules the ui work on the main queue, **and** it  posts the ui work to "execute js now".
* In "execute js now" (main thread):
   * This diff makes "execute js now" stateful: it keeps a "pending ui block."
   * Before capturing the runtime, the "execute js now" executes "pending ui work", if it exists.
   * While sleeping waiting for runtime capture, "execute js now" can wake up, and execute "pending ui work." It goes back to sleep afterwards, waiting for runtime capture.

## Mitigation: Deadlock facebook#1
**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime capture

**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

The main thread wakes up in "execute js now":
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block." The block, also scheduled on the main thread, noops henceforth.
* Main thread goes back to sleep, waiting for runtime capture.
* The js thread wakes up, moves on to the next task.

**Result:** The runtime is captured by the main thread.

| {F1978010383} | {F1978010363} |  {F1978010371} |  {F1978010379} |

![image](https://github.com/user-attachments/assets/f53cb10c-7801-46be-934a-96af7d5f5fab)

## Mitigation: Deadlock facebook#2
**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

**Main thread**: execute js now
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block" immediately. The block, also scheduled on the main thread, noops henceforth.
* Js thread wakes up and moves onto the next task.

**Result:** Main thread captures the runtime.

|  {F1978010525}  |  {F1978010533} |  {F1978010542} |

![image](https://github.com/user-attachments/assets/9e0ca5ef-fab6-4a26-bcca-d79d36624d5d)

Differential Revision: D74769326
RSNara added a commit to RSNara/react-native that referenced this pull request May 23, 2025
Summary:
Pull Request resolved: facebook#51425

# Problem

React native's new architecture will allow components to do sync render/events. That means they'll makes synchronous dispatches from main thread to the js thread, to capture the runtime so that they can execute js on the main thread.

But, the js thread already as a bunch of synchronous calls to the main thread. So, if any of those js -> ui sync calls happen concurrently with a synchronous render, the application will deadlock.

This diff is an attempt to mitigate all those deadlocks.

## Context
How js execution from the main thread works:

* Main thread puts a block on the js thread, to capture the js runtime. Main thread is put to sleep.
* Js thread executes "runtime capture block". The runtime is captured for the main thread. The js thread is put to sleep.
* Main thread wakes up, noticing that the runtime is captured. It executes its js code with the captured runtime. Then, it releases the runtime, which wakes up the js thread. Both the main and js thread move on to other tasks.

How synchronous js -> main thread calls work:
* Js thread puts a ui block on the main queue.
* Js thread goes to sleep until that ui block executes on the main thread.

## Deadlock facebook#1
**Main thread**: execute js now:
  * Main thread puts a block on the js queue, to capture the runtime.
 * Main thread then then goes to sleep, waiting for runtime to be captured

**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep, waiting for that block to execute.

**Result:** The application deadlocks

| {F1978009555} |  {F1978009612} |

![image](https://github.com/user-attachments/assets/325a62f4-d5b7-492d-a114-efb738556239)

## Deadlock facebook#2
**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep waiting for that block to execute.

**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime to be captured

**Result:** The application deadlocks

|  {F1978009690}  | {F1978009701} |

![image](https://github.com/user-attachments/assets/13a6ea17-a55d-453d-9291-d1c8007ecffa)

# Changes
This diff attempts to fix those deadlocks. How:
* In "execute ui code synchronously" (js thread):
   * Before going to sleep, the js thread schedules the ui work on the main queue, **and** it  posts the ui work to "execute js now".
* In "execute js now" (main thread):
   * This diff makes "execute js now" stateful: it keeps a "pending ui block."
   * Before capturing the runtime, the "execute js now" executes "pending ui work", if it exists.
   * While sleeping waiting for runtime capture, "execute js now" can wake up, and execute "pending ui work." It goes back to sleep afterwards, waiting for runtime capture.

## Mitigation: Deadlock facebook#1
**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime capture

**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

The main thread wakes up in "execute js now":
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block." The block, also scheduled on the main thread, noops henceforth.
* Main thread goes back to sleep, waiting for runtime capture.
* The js thread wakes up, moves on to the next task.

**Result:** The runtime is captured by the main thread.

| {F1978010383} | {F1978010363} |  {F1978010371} |  {F1978010379} |

![image](https://github.com/user-attachments/assets/f53cb10c-7801-46be-934a-96af7d5f5fab)

## Mitigation: Deadlock facebook#2
**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

**Main thread**: execute js now
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block" immediately. The block, also scheduled on the main thread, noops henceforth.
* Js thread wakes up and moves onto the next task.

**Result:** Main thread captures the runtime.

|  {F1978010525}  |  {F1978010533} |  {F1978010542} |

![image](https://github.com/user-attachments/assets/9e0ca5ef-fab6-4a26-bcca-d79d36624d5d)

Differential Revision: D74769326
RSNara added a commit to RSNara/react-native that referenced this pull request May 24, 2025
Summary:
Pull Request resolved: facebook#51425

# Problem

React native's new architecture will allow components to do sync render/events. That means they'll makes synchronous dispatches from main thread to the js thread, to capture the runtime so that they can execute js on the main thread.

But, the js thread already as a bunch of synchronous calls to the main thread. So, if any of those js -> ui sync calls happen concurrently with a synchronous render, the application will deadlock.

This diff is an attempt to mitigate all those deadlocks.

## Context
How js execution from the main thread works:

* Main thread puts a block on the js thread, to capture the js runtime. Main thread is put to sleep.
* Js thread executes "runtime capture block". The runtime is captured for the main thread. The js thread is put to sleep.
* Main thread wakes up, noticing that the runtime is captured. It executes its js code with the captured runtime. Then, it releases the runtime, which wakes up the js thread. Both the main and js thread move on to other tasks.

How synchronous js -> main thread calls work:
* Js thread puts a ui block on the main queue.
* Js thread goes to sleep until that ui block executes on the main thread.

## Deadlock facebook#1
**Main thread**: execute js now:
  * Main thread puts a block on the js queue, to capture the runtime.
 * Main thread then then goes to sleep, waiting for runtime to be captured

**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep, waiting for that block to execute.

**Result:** The application deadlocks

| {F1978009555} |  {F1978009612} |

![image](https://github.com/user-attachments/assets/325a62f4-d5b7-492d-a114-efb738556239)

## Deadlock facebook#2
**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep waiting for that block to execute.

**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime to be captured

**Result:** The application deadlocks

|  {F1978009690}  | {F1978009701} |

![image](https://github.com/user-attachments/assets/13a6ea17-a55d-453d-9291-d1c8007ecffa)

# Changes
This diff attempts to fix those deadlocks. How:
* In "execute ui code synchronously" (js thread):
   * Before going to sleep, the js thread schedules the ui work on the main queue, **and** it  posts the ui work to "execute js now".
* In "execute js now" (main thread):
   * This diff makes "execute js now" stateful: it keeps a "pending ui block."
   * Before capturing the runtime, the "execute js now" executes "pending ui work", if it exists.
   * While sleeping waiting for runtime capture, "execute js now" can wake up, and execute "pending ui work." It goes back to sleep afterwards, waiting for runtime capture.

## Mitigation: Deadlock facebook#1
**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime capture

**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

The main thread wakes up in "execute js now":
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block." The block, also scheduled on the main thread, noops henceforth.
* Main thread goes back to sleep, waiting for runtime capture.
* The js thread wakes up, moves on to the next task.

**Result:** The runtime is captured by the main thread.

| {F1978010383} | {F1978010363} |  {F1978010371} |  {F1978010379} |

![image](https://github.com/user-attachments/assets/f53cb10c-7801-46be-934a-96af7d5f5fab)

## Mitigation: Deadlock facebook#2
**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

**Main thread**: execute js now
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block" immediately. The block, also scheduled on the main thread, noops henceforth.
* Js thread wakes up and moves onto the next task.

**Result:** Main thread captures the runtime.

|  {F1978010525}  |  {F1978010533} |  {F1978010542} |

![image](https://github.com/user-attachments/assets/9e0ca5ef-fab6-4a26-bcca-d79d36624d5d)

Differential Revision: D74769326
RSNara added a commit to RSNara/react-native that referenced this pull request May 24, 2025
Summary:
Pull Request resolved: facebook#51425

# Problem

React native's new architecture will allow components to do sync render/events. That means they'll makes synchronous dispatches from main thread to the js thread, to capture the runtime so that they can execute js on the main thread.

But, the js thread already as a bunch of synchronous calls to the main thread. So, if any of those js -> ui sync calls happen concurrently with a synchronous render, the application will deadlock.

This diff is an attempt to mitigate all those deadlocks.

## Context
How js execution from the main thread works:

* Main thread puts a block on the js thread, to capture the js runtime. Main thread is put to sleep.
* Js thread executes "runtime capture block". The runtime is captured for the main thread. The js thread is put to sleep.
* Main thread wakes up, noticing that the runtime is captured. It executes its js code with the captured runtime. Then, it releases the runtime, which wakes up the js thread. Both the main and js thread move on to other tasks.

How synchronous js -> main thread calls work:
* Js thread puts a ui block on the main queue.
* Js thread goes to sleep until that ui block executes on the main thread.

## Deadlock facebook#1
**Main thread**: execute js now:
  * Main thread puts a block on the js queue, to capture the runtime.
 * Main thread then then goes to sleep, waiting for runtime to be captured

**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep, waiting for that block to execute.

**Result:** The application deadlocks

| {F1978009555} |  {F1978009612} |

![image](https://github.com/user-attachments/assets/325a62f4-d5b7-492d-a114-efb738556239)

## Deadlock facebook#2
**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep waiting for that block to execute.

**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime to be captured

**Result:** The application deadlocks

|  {F1978009690}  | {F1978009701} |

![image](https://github.com/user-attachments/assets/13a6ea17-a55d-453d-9291-d1c8007ecffa)

# Changes
This diff attempts to fix those deadlocks. How:
* In "execute ui code synchronously" (js thread):
   * Before going to sleep, the js thread schedules the ui work on the main queue, **and** it  posts the ui work to "execute js now".
* In "execute js now" (main thread):
   * This diff makes "execute js now" stateful: it keeps a "pending ui block."
   * Before capturing the runtime, the "execute js now" executes "pending ui work", if it exists.
   * While sleeping waiting for runtime capture, "execute js now" can wake up, and execute "pending ui work." It goes back to sleep afterwards, waiting for runtime capture.

## Mitigation: Deadlock facebook#1
**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime capture

**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

The main thread wakes up in "execute js now":
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block." The block, also scheduled on the main thread, noops henceforth.
* Main thread goes back to sleep, waiting for runtime capture.
* The js thread wakes up, moves on to the next task.

**Result:** The runtime is captured by the main thread.

| {F1978010383} | {F1978010363} |  {F1978010371} |  {F1978010379} |

![image](https://github.com/user-attachments/assets/f53cb10c-7801-46be-934a-96af7d5f5fab)

## Mitigation: Deadlock facebook#2
**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

**Main thread**: execute js now
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block" immediately. The block, also scheduled on the main thread, noops henceforth.
* Js thread wakes up and moves onto the next task.

**Result:** Main thread captures the runtime.

|  {F1978010525}  |  {F1978010533} |  {F1978010542} |

![image](https://github.com/user-attachments/assets/9e0ca5ef-fab6-4a26-bcca-d79d36624d5d)

Differential Revision: D74769326
RSNara added a commit to RSNara/react-native that referenced this pull request May 24, 2025
Summary:
Pull Request resolved: facebook#51425

# Problem

React native's new architecture will allow components to do sync render/events. That means they'll makes synchronous dispatches from main thread to the js thread, to capture the runtime so that they can execute js on the main thread.

But, the js thread already as a bunch of synchronous calls to the main thread. So, if any of those js -> ui sync calls happen concurrently with a synchronous render, the application will deadlock.

This diff is an attempt to mitigate all those deadlocks.

## Context
How js execution from the main thread works:

* Main thread puts a block on the js thread, to capture the js runtime. Main thread is put to sleep.
* Js thread executes "runtime capture block". The runtime is captured for the main thread. The js thread is put to sleep.
* Main thread wakes up, noticing that the runtime is captured. It executes its js code with the captured runtime. Then, it releases the runtime, which wakes up the js thread. Both the main and js thread move on to other tasks.

How synchronous js -> main thread calls work:
* Js thread puts a ui block on the main queue.
* Js thread goes to sleep until that ui block executes on the main thread.

## Deadlock facebook#1
**Main thread**: execute js now:
  * Main thread puts a block on the js queue, to capture the runtime.
 * Main thread then then goes to sleep, waiting for runtime to be captured

**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep, waiting for that block to execute.

**Result:** The application deadlocks

| {F1978009555} |  {F1978009612} |

![image](https://github.com/user-attachments/assets/325a62f4-d5b7-492d-a114-efb738556239)

## Deadlock facebook#2
**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep waiting for that block to execute.

**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime to be captured

**Result:** The application deadlocks

|  {F1978009690}  | {F1978009701} |

![image](https://github.com/user-attachments/assets/13a6ea17-a55d-453d-9291-d1c8007ecffa)

# Changes
This diff attempts to fix those deadlocks. How:
* In "execute ui code synchronously" (js thread):
   * Before going to sleep, the js thread schedules the ui work on the main queue, **and** it  posts the ui work to "execute js now".
* In "execute js now" (main thread):
   * This diff makes "execute js now" stateful: it keeps a "pending ui block."
   * Before capturing the runtime, the "execute js now" executes "pending ui work", if it exists.
   * While sleeping waiting for runtime capture, "execute js now" can wake up, and execute "pending ui work." It goes back to sleep afterwards, waiting for runtime capture.

## Mitigation: Deadlock facebook#1
**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime capture

**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

The main thread wakes up in "execute js now":
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block." The block, also scheduled on the main thread, noops henceforth.
* Main thread goes back to sleep, waiting for runtime capture.
* The js thread wakes up, moves on to the next task.

**Result:** The runtime is captured by the main thread.

| {F1978010383} | {F1978010363} |  {F1978010371} |  {F1978010379} |

![image](https://github.com/user-attachments/assets/f53cb10c-7801-46be-934a-96af7d5f5fab)

## Mitigation: Deadlock facebook#2
**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

**Main thread**: execute js now
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block" immediately. The block, also scheduled on the main thread, noops henceforth.
* Js thread wakes up and moves onto the next task.

**Result:** Main thread captures the runtime.

|  {F1978010525}  |  {F1978010533} |  {F1978010542} |

![image](https://github.com/user-attachments/assets/9e0ca5ef-fab6-4a26-bcca-d79d36624d5d)

Differential Revision: D74769326
RSNara added a commit to RSNara/react-native that referenced this pull request May 24, 2025
Summary:
Pull Request resolved: facebook#51425

# Problem

React native's new architecture will allow components to do sync render/events. That means they'll makes synchronous dispatches from main thread to the js thread, to capture the runtime so that they can execute js on the main thread.

But, the js thread already as a bunch of synchronous calls to the main thread. So, if any of those js -> ui sync calls happen concurrently with a synchronous render, the application will deadlock.

This diff is an attempt to mitigate all those deadlocks.

## Context
How js execution from the main thread works:

* Main thread puts a block on the js thread, to capture the js runtime. Main thread is put to sleep.
* Js thread executes "runtime capture block". The runtime is captured for the main thread. The js thread is put to sleep.
* Main thread wakes up, noticing that the runtime is captured. It executes its js code with the captured runtime. Then, it releases the runtime, which wakes up the js thread. Both the main and js thread move on to other tasks.

How synchronous js -> main thread calls work:
* Js thread puts a ui block on the main queue.
* Js thread goes to sleep until that ui block executes on the main thread.

## Deadlock facebook#1
**Main thread**: execute js now:
  * Main thread puts a block on the js queue, to capture the runtime.
 * Main thread then then goes to sleep, waiting for runtime to be captured

**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep, waiting for that block to execute.

**Result:** The application deadlocks

| {F1978009555} |  {F1978009612} |

![image](https://github.com/user-attachments/assets/325a62f4-d5b7-492d-a114-efb738556239)

## Deadlock facebook#2
**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep waiting for that block to execute.

**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime to be captured

**Result:** The application deadlocks

|  {F1978009690}  | {F1978009701} |

![image](https://github.com/user-attachments/assets/13a6ea17-a55d-453d-9291-d1c8007ecffa)

# Changes
This diff attempts to fix those deadlocks. How:
* In "execute ui code synchronously" (js thread):
   * Before going to sleep, the js thread schedules the ui work on the main queue, **and** it  posts the ui work to "execute js now".
* In "execute js now" (main thread):
   * This diff makes "execute js now" stateful: it keeps a "pending ui block."
   * Before capturing the runtime, the "execute js now" executes "pending ui work", if it exists.
   * While sleeping waiting for runtime capture, "execute js now" can wake up, and execute "pending ui work." It goes back to sleep afterwards, waiting for runtime capture.

## Mitigation: Deadlock facebook#1
**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime capture

**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

The main thread wakes up in "execute js now":
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block." The block, also scheduled on the main thread, noops henceforth.
* Main thread goes back to sleep, waiting for runtime capture.
* The js thread wakes up, moves on to the next task.

**Result:** The runtime is captured by the main thread.

| {F1978010383} | {F1978010363} |  {F1978010371} |  {F1978010379} |

![image](https://github.com/user-attachments/assets/f53cb10c-7801-46be-934a-96af7d5f5fab)

## Mitigation: Deadlock facebook#2
**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

**Main thread**: execute js now
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block" immediately. The block, also scheduled on the main thread, noops henceforth.
* Js thread wakes up and moves onto the next task.

**Result:** Main thread captures the runtime.

|  {F1978010525}  |  {F1978010533} |  {F1978010542} |

![image](https://github.com/user-attachments/assets/9e0ca5ef-fab6-4a26-bcca-d79d36624d5d)

Differential Revision: D74769326
RSNara added a commit to RSNara/react-native that referenced this pull request May 27, 2025
Summary:
Pull Request resolved: facebook#51425

# Problem

React native's new architecture will allow components to do sync render/events. That means they'll makes synchronous dispatches from main thread to the js thread, to capture the runtime so that they can execute js on the main thread.

But, the js thread already as a bunch of synchronous calls to the main thread. So, if any of those js -> ui sync calls happen concurrently with a synchronous render, the application will deadlock.

This diff is an attempt to mitigate all those deadlocks.

## Context
How js execution from the main thread works:

* Main thread puts a block on the js thread, to capture the js runtime. Main thread is put to sleep.
* Js thread executes "runtime capture block". The runtime is captured for the main thread. The js thread is put to sleep.
* Main thread wakes up, noticing that the runtime is captured. It executes its js code with the captured runtime. Then, it releases the runtime, which wakes up the js thread. Both the main and js thread move on to other tasks.

How synchronous js -> main thread calls work:
* Js thread puts a ui block on the main queue.
* Js thread goes to sleep until that ui block executes on the main thread.

## Deadlock facebook#1
**Main thread**: execute js now:
  * Main thread puts a block on the js queue, to capture the runtime.
 * Main thread then then goes to sleep, waiting for runtime to be captured

**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep, waiting for that block to execute.

**Result:** The application deadlocks

| {F1978009555} |  {F1978009612} |

![image](https://github.com/user-attachments/assets/325a62f4-d5b7-492d-a114-efb738556239)

## Deadlock facebook#2
**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep waiting for that block to execute.

**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime to be captured

**Result:** The application deadlocks

|  {F1978009690}  | {F1978009701} |

![image](https://github.com/user-attachments/assets/13a6ea17-a55d-453d-9291-d1c8007ecffa)

# Changes
This diff attempts to fix those deadlocks. How:
* In "execute ui code synchronously" (js thread):
   * Before going to sleep, the js thread schedules the ui work on the main queue, **and** it  posts the ui work to "execute js now".
* In "execute js now" (main thread):
   * This diff makes "execute js now" stateful: it keeps a "pending ui block."
   * Before capturing the runtime, the "execute js now" executes "pending ui work", if it exists.
   * While sleeping waiting for runtime capture, "execute js now" can wake up, and execute "pending ui work." It goes back to sleep afterwards, waiting for runtime capture.

## Mitigation: Deadlock facebook#1
**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime capture

**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

The main thread wakes up in "execute js now":
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block." The block, also scheduled on the main thread, noops henceforth.
* Main thread goes back to sleep, waiting for runtime capture.
* The js thread wakes up, moves on to the next task.

**Result:** The runtime is captured by the main thread.

| {F1978010383} | {F1978010363} |  {F1978010371} |  {F1978010379} |

![image](https://github.com/user-attachments/assets/f53cb10c-7801-46be-934a-96af7d5f5fab)

## Mitigation: Deadlock facebook#2
**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

**Main thread**: execute js now
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block" immediately. The block, also scheduled on the main thread, noops henceforth.
* Js thread wakes up and moves onto the next task.

**Result:** Main thread captures the runtime.

|  {F1978010525}  |  {F1978010533} |  {F1978010542} |

![image](https://github.com/user-attachments/assets/9e0ca5ef-fab6-4a26-bcca-d79d36624d5d)

Differential Revision: D74769326
RSNara added a commit to RSNara/react-native that referenced this pull request May 28, 2025
Summary:
Pull Request resolved: facebook#51425

# Problem

React native's new architecture will allow components to do sync render/events. That means they'll makes synchronous dispatches from main thread to the js thread, to capture the runtime so that they can execute js on the main thread.

But, the js thread already as a bunch of synchronous calls to the main thread. So, if any of those js -> ui sync calls happen concurrently with a synchronous render, the application will deadlock.

This diff is an attempt to mitigate all those deadlocks.

## Context
How js execution from the main thread works:

* Main thread puts a block on the js thread, to capture the js runtime. Main thread is put to sleep.
* Js thread executes "runtime capture block". The runtime is captured for the main thread. The js thread is put to sleep.
* Main thread wakes up, noticing that the runtime is captured. It executes its js code with the captured runtime. Then, it releases the runtime, which wakes up the js thread. Both the main and js thread move on to other tasks.

How synchronous js -> main thread calls work:
* Js thread puts a ui block on the main queue.
* Js thread goes to sleep until that ui block executes on the main thread.

## Deadlock facebook#1
**Main thread**: execute js now:
  * Main thread puts a block on the js queue, to capture the runtime.
 * Main thread then then goes to sleep, waiting for runtime to be captured

**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep, waiting for that block to execute.

**Result:** The application deadlocks

| {F1978009555} |  {F1978009612} |

![image](https://github.com/user-attachments/assets/325a62f4-d5b7-492d-a114-efb738556239)

## Deadlock facebook#2
**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep waiting for that block to execute.

**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime to be captured

**Result:** The application deadlocks

|  {F1978009690}  | {F1978009701} |

![image](https://github.com/user-attachments/assets/13a6ea17-a55d-453d-9291-d1c8007ecffa)

# Changes
This diff attempts to fix those deadlocks. How:
* In "execute ui code synchronously" (js thread):
   * Before going to sleep, the js thread schedules the ui work on the main queue, **and** it  posts the ui work to "execute js now".
* In "execute js now" (main thread):
   * This diff makes "execute js now" stateful: it keeps a "pending ui block."
   * Before capturing the runtime, the "execute js now" executes "pending ui work", if it exists.
   * While sleeping waiting for runtime capture, "execute js now" can wake up, and execute "pending ui work." It goes back to sleep afterwards, waiting for runtime capture.

## Mitigation: Deadlock facebook#1
**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime capture

**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

The main thread wakes up in "execute js now":
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block." The block, also scheduled on the main thread, noops henceforth.
* Main thread goes back to sleep, waiting for runtime capture.
* The js thread wakes up, moves on to the next task.

**Result:** The runtime is captured by the main thread.

| {F1978010383} | {F1978010363} |  {F1978010371} |  {F1978010379} |

![image](https://github.com/user-attachments/assets/f53cb10c-7801-46be-934a-96af7d5f5fab)

## Mitigation: Deadlock facebook#2
**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

**Main thread**: execute js now
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block" immediately. The block, also scheduled on the main thread, noops henceforth.
* Js thread wakes up and moves onto the next task.

**Result:** Main thread captures the runtime.

|  {F1978010525}  |  {F1978010533} |  {F1978010542} |

![image](https://github.com/user-attachments/assets/9e0ca5ef-fab6-4a26-bcca-d79d36624d5d)

Differential Revision: D74769326
RSNara added a commit to RSNara/react-native that referenced this pull request May 28, 2025
Summary:
Pull Request resolved: facebook#51425

# Problem

React native's new architecture will allow components to do sync render/events. That means they'll makes synchronous dispatches from main thread to the js thread, to capture the runtime so that they can execute js on the main thread.

But, the js thread already as a bunch of synchronous calls to the main thread. So, if any of those js -> ui sync calls happen concurrently with a synchronous render, the application will deadlock.

This diff is an attempt to mitigate all those deadlocks.

## Context
How js execution from the main thread works:

* Main thread puts a block on the js thread, to capture the js runtime. Main thread is put to sleep.
* Js thread executes "runtime capture block". The runtime is captured for the main thread. The js thread is put to sleep.
* Main thread wakes up, noticing that the runtime is captured. It executes its js code with the captured runtime. Then, it releases the runtime, which wakes up the js thread. Both the main and js thread move on to other tasks.

How synchronous js -> main thread calls work:
* Js thread puts a ui block on the main queue.
* Js thread goes to sleep until that ui block executes on the main thread.

## Deadlock facebook#1
**Main thread**: execute js now:
  * Main thread puts a block on the js queue, to capture the runtime.
 * Main thread then then goes to sleep, waiting for runtime to be captured

**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep, waiting for that block to execute.

**Result:** The application deadlocks

| {F1978009555} |  {F1978009612} |

![image](https://github.com/user-attachments/assets/325a62f4-d5b7-492d-a114-efb738556239)

## Deadlock facebook#2
**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep waiting for that block to execute.

**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime to be captured

**Result:** The application deadlocks

|  {F1978009690}  | {F1978009701} |

![image](https://github.com/user-attachments/assets/13a6ea17-a55d-453d-9291-d1c8007ecffa)

# Changes
This diff attempts to fix those deadlocks. How:
* In "execute ui code synchronously" (js thread):
   * Before going to sleep, the js thread schedules the ui work on the main queue, **and** it  posts the ui work to "execute js now".
* In "execute js now" (main thread):
   * This diff makes "execute js now" stateful: it keeps a "pending ui block."
   * Before capturing the runtime, the "execute js now" executes "pending ui work", if it exists.
   * While sleeping waiting for runtime capture, "execute js now" can wake up, and execute "pending ui work." It goes back to sleep afterwards, waiting for runtime capture.

## Mitigation: Deadlock facebook#1
**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime capture

**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

The main thread wakes up in "execute js now":
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block." The block, also scheduled on the main thread, noops henceforth.
* Main thread goes back to sleep, waiting for runtime capture.
* The js thread wakes up, moves on to the next task.

**Result:** The runtime is captured by the main thread.

| {F1978010383} | {F1978010363} |  {F1978010371} |  {F1978010379} |

![image](https://github.com/user-attachments/assets/f53cb10c-7801-46be-934a-96af7d5f5fab)

## Mitigation: Deadlock facebook#2
**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

**Main thread**: execute js now
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block" immediately. The block, also scheduled on the main thread, noops henceforth.
* Js thread wakes up and moves onto the next task.

**Result:** Main thread captures the runtime.

|  {F1978010525}  |  {F1978010533} |  {F1978010542} |

![image](https://github.com/user-attachments/assets/9e0ca5ef-fab6-4a26-bcca-d79d36624d5d)

Differential Revision: D74769326
RSNara added a commit to RSNara/react-native that referenced this pull request May 28, 2025
Summary:

# Problem

React native's new architecture will allow components to do sync render/events. That means they'll makes synchronous dispatches from main thread to the js thread, to capture the runtime so that they can execute js on the main thread.

But, the js thread already as a bunch of synchronous calls to the main thread. So, if any of those js -> ui sync calls happen concurrently with a synchronous render, the application will deadlock.

This diff is an attempt to mitigate all those deadlocks.

## Context
How js execution from the main thread works:

* Main thread puts a block on the js thread, to capture the js runtime. Main thread is put to sleep.
* Js thread executes "runtime capture block". The runtime is captured for the main thread. The js thread is put to sleep.
* Main thread wakes up, noticing that the runtime is captured. It executes its js code with the captured runtime. Then, it releases the runtime, which wakes up the js thread. Both the main and js thread move on to other tasks.

How synchronous js -> main thread calls work:
* Js thread puts a ui block on the main queue.
* Js thread goes to sleep until that ui block executes on the main thread.



## Deadlock facebook#1
**Main thread**: execute js now:
  * Main thread puts a block on the js queue, to capture the runtime.
 * Main thread then then goes to sleep, waiting for runtime to be captured

**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep, waiting for that block to execute.

**Result:** The application deadlocks

| {F1978009555} |  {F1978009612} |

![image](https://github.com/user-attachments/assets/325a62f4-d5b7-492d-a114-efb738556239)

## Deadlock facebook#2
**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep waiting for that block to execute.

**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime to be captured

**Result:** The application deadlocks

|  {F1978009690}  | {F1978009701} |

![image](https://github.com/user-attachments/assets/13a6ea17-a55d-453d-9291-d1c8007ecffa)

# Changes
This diff attempts to fix those deadlocks. How:
* In "execute ui code synchronously" (js thread):
   * Before going to sleep, the js thread schedules the ui work on the main queue, **and** it  posts the ui work to "execute js now".
* In "execute js now" (main thread):
   * This diff makes "execute js now" stateful: it keeps a "pending ui block."
   * Before capturing the runtime, the "execute js now" executes "pending ui work", if it exists.
   * While sleeping waiting for runtime capture, "execute js now" can wake up, and execute "pending ui work." It goes back to sleep afterwards, waiting for runtime capture.

## Mitigation: Deadlock facebook#1
**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime capture

**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

The main thread wakes up in "execute js now":
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block." The block, also scheduled on the main thread, noops henceforth.
* Main thread goes back to sleep, waiting for runtime capture.
* The js thread wakes up, moves on to the next task.

**Result:** The runtime is captured by the main thread.

| {F1978010383} | {F1978010363} |  {F1978010371} |  {F1978010379} |

![image](https://github.com/user-attachments/assets/f53cb10c-7801-46be-934a-96af7d5f5fab)

## Mitigation: Deadlock facebook#2
**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

**Main thread**: execute js now
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block" immediately. The block, also scheduled on the main thread, noops henceforth.
* Js thread wakes up and moves onto the next task.

**Result:** Main thread captures the runtime.

|  {F1978010525}  |  {F1978010533} |  {F1978010542} |

![image](https://github.com/user-attachments/assets/9e0ca5ef-fab6-4a26-bcca-d79d36624d5d)

Differential Revision: D74769326
RSNara added a commit to RSNara/react-native that referenced this pull request May 28, 2025
Summary:

# Problem

React native's new architecture will allow components to do sync render/events. That means they'll makes synchronous dispatches from main thread to the js thread, to capture the runtime so that they can execute js on the main thread.

But, the js thread already as a bunch of synchronous calls to the main thread. So, if any of those js -> ui sync calls happen concurrently with a synchronous render, the application will deadlock.

This diff is an attempt to mitigate all those deadlocks.

## Context
How js execution from the main thread works:

* Main thread puts a block on the js thread, to capture the js runtime. Main thread is put to sleep.
* Js thread executes "runtime capture block". The runtime is captured for the main thread. The js thread is put to sleep.
* Main thread wakes up, noticing that the runtime is captured. It executes its js code with the captured runtime. Then, it releases the runtime, which wakes up the js thread. Both the main and js thread move on to other tasks.

How synchronous js -> main thread calls work:
* Js thread puts a ui block on the main queue.
* Js thread goes to sleep until that ui block executes on the main thread.



## Deadlock facebook#1
**Main thread**: execute js now:
  * Main thread puts a block on the js queue, to capture the runtime.
 * Main thread then then goes to sleep, waiting for runtime to be captured

**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep, waiting for that block to execute.

**Result:** The application deadlocks

| {F1978009555} |  {F1978009612} |

![image](https://github.com/user-attachments/assets/325a62f4-d5b7-492d-a114-efb738556239)

## Deadlock facebook#2
**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep waiting for that block to execute.

**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime to be captured

**Result:** The application deadlocks

|  {F1978009690}  | {F1978009701} |

![image](https://github.com/user-attachments/assets/13a6ea17-a55d-453d-9291-d1c8007ecffa)

# Changes
This diff attempts to fix those deadlocks. How:
* In "execute ui code synchronously" (js thread):
   * Before going to sleep, the js thread schedules the ui work on the main queue, **and** it  posts the ui work to "execute js now".
* In "execute js now" (main thread):
   * This diff makes "execute js now" stateful: it keeps a "pending ui block."
   * Before capturing the runtime, the "execute js now" executes "pending ui work", if it exists.
   * While sleeping waiting for runtime capture, "execute js now" can wake up, and execute "pending ui work." It goes back to sleep afterwards, waiting for runtime capture.

## Mitigation: Deadlock facebook#1
**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime capture

**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

The main thread wakes up in "execute js now":
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block." The block, also scheduled on the main thread, noops henceforth.
* Main thread goes back to sleep, waiting for runtime capture.
* The js thread wakes up, moves on to the next task.

**Result:** The runtime is captured by the main thread.

| {F1978010383} | {F1978010363} |  {F1978010371} |  {F1978010379} |

![image](https://github.com/user-attachments/assets/f53cb10c-7801-46be-934a-96af7d5f5fab)

## Mitigation: Deadlock facebook#2
**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

**Main thread**: execute js now
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block" immediately. The block, also scheduled on the main thread, noops henceforth.
* Js thread wakes up and moves onto the next task.

**Result:** Main thread captures the runtime.

|  {F1978010525}  |  {F1978010533} |  {F1978010542} |

![image](https://github.com/user-attachments/assets/9e0ca5ef-fab6-4a26-bcca-d79d36624d5d)

Differential Revision: D74769326
RSNara added a commit to RSNara/react-native that referenced this pull request May 28, 2025
Summary:
Pull Request resolved: facebook#51425

# Problem

React native's new architecture will allow components to do sync render/events. That means they'll makes synchronous dispatches from main thread to the js thread, to capture the runtime so that they can execute js on the main thread.

But, the js thread already as a bunch of synchronous calls to the main thread. So, if any of those js -> ui sync calls happen concurrently with a synchronous render, the application will deadlock.

This diff is an attempt to mitigate all those deadlocks.

## Context
How js execution from the main thread works:

* Main thread puts a block on the js thread, to capture the js runtime. Main thread is put to sleep.
* Js thread executes "runtime capture block". The runtime is captured for the main thread. The js thread is put to sleep.
* Main thread wakes up, noticing that the runtime is captured. It executes its js code with the captured runtime. Then, it releases the runtime, which wakes up the js thread. Both the main and js thread move on to other tasks.

How synchronous js -> main thread calls work:
* Js thread puts a ui block on the main queue.
* Js thread goes to sleep until that ui block executes on the main thread.

## Deadlock facebook#1
**Main thread**: execute js now:
  * Main thread puts a block on the js queue, to capture the runtime.
 * Main thread then then goes to sleep, waiting for runtime to be captured

**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep, waiting for that block to execute.

**Result:** The application deadlocks

| {F1978009555} |  {F1978009612} |

![image](https://github.com/user-attachments/assets/325a62f4-d5b7-492d-a114-efb738556239)

## Deadlock facebook#2
**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep waiting for that block to execute.

**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime to be captured

**Result:** The application deadlocks

|  {F1978009690}  | {F1978009701} |

![image](https://github.com/user-attachments/assets/13a6ea17-a55d-453d-9291-d1c8007ecffa)

# Changes
This diff attempts to fix those deadlocks. How:
* In "execute ui code synchronously" (js thread):
   * Before going to sleep, the js thread schedules the ui work on the main queue, **and** it  posts the ui work to "execute js now".
* In "execute js now" (main thread):
   * This diff makes "execute js now" stateful: it keeps a "pending ui block."
   * Before capturing the runtime, the "execute js now" executes "pending ui work", if it exists.
   * While sleeping waiting for runtime capture, "execute js now" can wake up, and execute "pending ui work." It goes back to sleep afterwards, waiting for runtime capture.

## Mitigation: Deadlock facebook#1
**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime capture

**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

The main thread wakes up in "execute js now":
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block." The block, also scheduled on the main thread, noops henceforth.
* Main thread goes back to sleep, waiting for runtime capture.
* The js thread wakes up, moves on to the next task.

**Result:** The runtime is captured by the main thread.

| {F1978010383} | {F1978010363} |  {F1978010371} |  {F1978010379} |

![image](https://github.com/user-attachments/assets/f53cb10c-7801-46be-934a-96af7d5f5fab)

## Mitigation: Deadlock facebook#2
**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

**Main thread**: execute js now
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block" immediately. The block, also scheduled on the main thread, noops henceforth.
* Js thread wakes up and moves onto the next task.

**Result:** Main thread captures the runtime.

|  {F1978010525}  |  {F1978010533} |  {F1978010542} |

![image](https://github.com/user-attachments/assets/9e0ca5ef-fab6-4a26-bcca-d79d36624d5d)

Differential Revision: D74769326
RSNara added a commit to RSNara/react-native that referenced this pull request May 28, 2025
Summary:
Pull Request resolved: facebook#51425

# Problem

React native's new architecture will allow components to do sync render/events. That means they'll makes synchronous dispatches from main thread to the js thread, to capture the runtime so that they can execute js on the main thread.

But, the js thread already as a bunch of synchronous calls to the main thread. So, if any of those js -> ui sync calls happen concurrently with a synchronous render, the application will deadlock.

This diff is an attempt to mitigate all those deadlocks.

## Context
How js execution from the main thread works:

* Main thread puts a block on the js thread, to capture the js runtime. Main thread is put to sleep.
* Js thread executes "runtime capture block". The runtime is captured for the main thread. The js thread is put to sleep.
* Main thread wakes up, noticing that the runtime is captured. It executes its js code with the captured runtime. Then, it releases the runtime, which wakes up the js thread. Both the main and js thread move on to other tasks.

How synchronous js -> main thread calls work:
* Js thread puts a ui block on the main queue.
* Js thread goes to sleep until that ui block executes on the main thread.

## Deadlock facebook#1
**Main thread**: execute js now:
  * Main thread puts a block on the js queue, to capture the runtime.
 * Main thread then then goes to sleep, waiting for runtime to be captured

**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep, waiting for that block to execute.

**Result:** The application deadlocks

| {F1978009555} |  {F1978009612} |

![image](https://github.com/user-attachments/assets/325a62f4-d5b7-492d-a114-efb738556239)

## Deadlock facebook#2
**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep waiting for that block to execute.

**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime to be captured

**Result:** The application deadlocks

|  {F1978009690}  | {F1978009701} |

![image](https://github.com/user-attachments/assets/13a6ea17-a55d-453d-9291-d1c8007ecffa)

# Changes
This diff attempts to fix those deadlocks. How:
* In "execute ui code synchronously" (js thread):
   * Before going to sleep, the js thread schedules the ui work on the main queue, **and** it  posts the ui work to "execute js now".
* In "execute js now" (main thread):
   * This diff makes "execute js now" stateful: it keeps a "pending ui block."
   * Before capturing the runtime, the "execute js now" executes "pending ui work", if it exists.
   * While sleeping waiting for runtime capture, "execute js now" can wake up, and execute "pending ui work." It goes back to sleep afterwards, waiting for runtime capture.

## Mitigation: Deadlock facebook#1
**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime capture

**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

The main thread wakes up in "execute js now":
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block." The block, also scheduled on the main thread, noops henceforth.
* Main thread goes back to sleep, waiting for runtime capture.
* The js thread wakes up, moves on to the next task.

**Result:** The runtime is captured by the main thread.

| {F1978010383} | {F1978010363} |  {F1978010371} |  {F1978010379} |

![image](https://github.com/user-attachments/assets/f53cb10c-7801-46be-934a-96af7d5f5fab)

## Mitigation: Deadlock facebook#2
**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

**Main thread**: execute js now
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block" immediately. The block, also scheduled on the main thread, noops henceforth.
* Js thread wakes up and moves onto the next task.

**Result:** Main thread captures the runtime.

|  {F1978010525}  |  {F1978010533} |  {F1978010542} |

![image](https://github.com/user-attachments/assets/9e0ca5ef-fab6-4a26-bcca-d79d36624d5d)

Differential Revision: D74769326
RSNara added a commit to RSNara/react-native that referenced this pull request Jun 13, 2025
Summary:
Pull Request resolved: facebook#51425

# Problem

React native's new architecture will allow components to do sync render/events. That means they'll makes synchronous dispatches from main thread to the js thread, to capture the runtime so that they can execute js on the main thread.

But, the js thread already as a bunch of synchronous calls to the main thread. So, if any of those js -> ui sync calls happen concurrently with a synchronous render, the application will deadlock.

This diff is an attempt to mitigate all those deadlocks.

## Context
How js execution from the main thread works:

* Main thread puts a block on the js thread, to capture the js runtime. Main thread is put to sleep.
* Js thread executes "runtime capture block". The runtime is captured for the main thread. The js thread is put to sleep.
* Main thread wakes up, noticing that the runtime is captured. It executes its js code with the captured runtime. Then, it releases the runtime, which wakes up the js thread. Both the main and js thread move on to other tasks.

How synchronous js -> main thread calls work:
* Js thread puts a ui block on the main queue.
* Js thread goes to sleep until that ui block executes on the main thread.

## Deadlock facebook#1
**Main thread**: execute js now:
  * Main thread puts a block on the js queue, to capture the runtime.
 * Main thread then then goes to sleep, waiting for runtime to be captured

**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep, waiting for that block to execute.

**Result:** The application deadlocks

| {F1978009555} |  {F1978009612} |

![image](https://github.com/user-attachments/assets/325a62f4-d5b7-492d-a114-efb738556239)

## Deadlock facebook#2
**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep waiting for that block to execute.

**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime to be captured

**Result:** The application deadlocks

|  {F1978009690}  | {F1978009701} |

![image](https://github.com/user-attachments/assets/13a6ea17-a55d-453d-9291-d1c8007ecffa)

# Changes
This diff attempts to fix those deadlocks. How:
* In "execute ui code synchronously" (js thread):
   * Before going to sleep, the js thread schedules the ui work on the main queue, **and** it  posts the ui work to "execute js now".
* In "execute js now" (main thread):
   * This diff makes "execute js now" stateful: it keeps a "pending ui block."
   * Before capturing the runtime, the "execute js now" executes "pending ui work", if it exists.
   * While sleeping waiting for runtime capture, "execute js now" can wake up, and execute "pending ui work." It goes back to sleep afterwards, waiting for runtime capture.

## Mitigation: Deadlock facebook#1
**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime capture

**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

The main thread wakes up in "execute js now":
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block." The block, also scheduled on the main thread, noops henceforth.
* Main thread goes back to sleep, waiting for runtime capture.
* The js thread wakes up, moves on to the next task.

**Result:** The runtime is captured by the main thread.

| {F1978010383} | {F1978010363} |  {F1978010371} |  {F1978010379} |

![image](https://github.com/user-attachments/assets/f53cb10c-7801-46be-934a-96af7d5f5fab)

## Mitigation: Deadlock facebook#2
**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

**Main thread**: execute js now
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block" immediately. The block, also scheduled on the main thread, noops henceforth.
* Js thread wakes up and moves onto the next task.

**Result:** Main thread captures the runtime.

|  {F1978010525}  |  {F1978010533} |  {F1978010542} |

![image](https://github.com/user-attachments/assets/9e0ca5ef-fab6-4a26-bcca-d79d36624d5d)

Reviewed By: javache

Differential Revision: D74769326
RSNara added a commit to RSNara/react-native that referenced this pull request Jun 13, 2025
Summary:
Pull Request resolved: facebook#51425

# Problem

React native's new architecture will allow components to do sync render/events. That means they'll makes synchronous dispatches from main thread to the js thread, to capture the runtime so that they can execute js on the main thread.

But, the js thread already as a bunch of synchronous calls to the main thread. So, if any of those js -> ui sync calls happen concurrently with a synchronous render, the application will deadlock.

This diff is an attempt to mitigate all those deadlocks.

## Context
How js execution from the main thread works:

* Main thread puts a block on the js thread, to capture the js runtime. Main thread is put to sleep.
* Js thread executes "runtime capture block". The runtime is captured for the main thread. The js thread is put to sleep.
* Main thread wakes up, noticing that the runtime is captured. It executes its js code with the captured runtime. Then, it releases the runtime, which wakes up the js thread. Both the main and js thread move on to other tasks.

How synchronous js -> main thread calls work:
* Js thread puts a ui block on the main queue.
* Js thread goes to sleep until that ui block executes on the main thread.

## Deadlock facebook#1
**Main thread**: execute js now:
  * Main thread puts a block on the js queue, to capture the runtime.
 * Main thread then then goes to sleep, waiting for runtime to be captured

**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep, waiting for that block to execute.

**Result:** The application deadlocks

| {F1978009555} |  {F1978009612} |

![image](https://github.com/user-attachments/assets/325a62f4-d5b7-492d-a114-efb738556239)

## Deadlock facebook#2
**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep waiting for that block to execute.

**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime to be captured

**Result:** The application deadlocks

|  {F1978009690}  | {F1978009701} |

![image](https://github.com/user-attachments/assets/13a6ea17-a55d-453d-9291-d1c8007ecffa)

# Changes
This diff attempts to fix those deadlocks. How:
* In "execute ui code synchronously" (js thread):
   * Before going to sleep, the js thread schedules the ui work on the main queue, **and** it  posts the ui work to "execute js now".
* In "execute js now" (main thread):
   * This diff makes "execute js now" stateful: it keeps a "pending ui block."
   * Before capturing the runtime, the "execute js now" executes "pending ui work", if it exists.
   * While sleeping waiting for runtime capture, "execute js now" can wake up, and execute "pending ui work." It goes back to sleep afterwards, waiting for runtime capture.

## Mitigation: Deadlock facebook#1
**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime capture

**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

The main thread wakes up in "execute js now":
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block." The block, also scheduled on the main thread, noops henceforth.
* Main thread goes back to sleep, waiting for runtime capture.
* The js thread wakes up, moves on to the next task.

**Result:** The runtime is captured by the main thread.

| {F1978010383} | {F1978010363} |  {F1978010371} |  {F1978010379} |

![image](https://github.com/user-attachments/assets/f53cb10c-7801-46be-934a-96af7d5f5fab)

## Mitigation: Deadlock facebook#2
**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

**Main thread**: execute js now
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block" immediately. The block, also scheduled on the main thread, noops henceforth.
* Js thread wakes up and moves onto the next task.

**Result:** Main thread captures the runtime.

|  {F1978010525}  |  {F1978010533} |  {F1978010542} |

![image](https://github.com/user-attachments/assets/9e0ca5ef-fab6-4a26-bcca-d79d36624d5d)

Reviewed By: javache

Differential Revision: D74769326
RSNara added a commit to RSNara/react-native that referenced this pull request Jun 13, 2025
Summary:
Pull Request resolved: facebook#51425

# Problem

React native's new architecture will allow components to do sync render/events. That means they'll makes synchronous dispatches from main thread to the js thread, to capture the runtime so that they can execute js on the main thread.

But, the js thread already as a bunch of synchronous calls to the main thread. So, if any of those js -> ui sync calls happen concurrently with a synchronous render, the application will deadlock.

This diff is an attempt to mitigate all those deadlocks.

## Context
How js execution from the main thread works:

* Main thread puts a block on the js thread, to capture the js runtime. Main thread is put to sleep.
* Js thread executes "runtime capture block". The runtime is captured for the main thread. The js thread is put to sleep.
* Main thread wakes up, noticing that the runtime is captured. It executes its js code with the captured runtime. Then, it releases the runtime, which wakes up the js thread. Both the main and js thread move on to other tasks.

How synchronous js -> main thread calls work:
* Js thread puts a ui block on the main queue.
* Js thread goes to sleep until that ui block executes on the main thread.

## Deadlock facebook#1
**Main thread**: execute js now:
  * Main thread puts a block on the js queue, to capture the runtime.
 * Main thread then then goes to sleep, waiting for runtime to be captured

**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep, waiting for that block to execute.

**Result:** The application deadlocks

| {F1978009555} |  {F1978009612} |

![image](https://github.com/user-attachments/assets/325a62f4-d5b7-492d-a114-efb738556239)

## Deadlock facebook#2
**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep waiting for that block to execute.

**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime to be captured

**Result:** The application deadlocks

|  {F1978009690}  | {F1978009701} |

![image](https://github.com/user-attachments/assets/13a6ea17-a55d-453d-9291-d1c8007ecffa)

# Changes
This diff attempts to fix those deadlocks. How:
* In "execute ui code synchronously" (js thread):
   * Before going to sleep, the js thread schedules the ui work on the main queue, **and** it  posts the ui work to "execute js now".
* In "execute js now" (main thread):
   * This diff makes "execute js now" stateful: it keeps a "pending ui block."
   * Before capturing the runtime, the "execute js now" executes "pending ui work", if it exists.
   * While sleeping waiting for runtime capture, "execute js now" can wake up, and execute "pending ui work." It goes back to sleep afterwards, waiting for runtime capture.

## Mitigation: Deadlock facebook#1
**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime capture

**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

The main thread wakes up in "execute js now":
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block." The block, also scheduled on the main thread, noops henceforth.
* Main thread goes back to sleep, waiting for runtime capture.
* The js thread wakes up, moves on to the next task.

**Result:** The runtime is captured by the main thread.

| {F1978010383} | {F1978010363} |  {F1978010371} |  {F1978010379} |

![image](https://github.com/user-attachments/assets/f53cb10c-7801-46be-934a-96af7d5f5fab)

## Mitigation: Deadlock facebook#2
**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

**Main thread**: execute js now
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block" immediately. The block, also scheduled on the main thread, noops henceforth.
* Js thread wakes up and moves onto the next task.

**Result:** Main thread captures the runtime.

|  {F1978010525}  |  {F1978010533} |  {F1978010542} |

![image](https://github.com/user-attachments/assets/9e0ca5ef-fab6-4a26-bcca-d79d36624d5d)

Changelog: [Internal]

Reviewed By: javache

Differential Revision: D74769326
RSNara added a commit to RSNara/react-native that referenced this pull request Jun 13, 2025
Summary:
Pull Request resolved: facebook#51425

# Problem

React native's new architecture will allow components to do sync render/events. That means they'll makes synchronous dispatches from main thread to the js thread, to capture the runtime so that they can execute js on the main thread.

But, the js thread already as a bunch of synchronous calls to the main thread. So, if any of those js -> ui sync calls happen concurrently with a synchronous render, the application will deadlock.

This diff is an attempt to mitigate all those deadlocks.

## Context
How js execution from the main thread works:

* Main thread puts a block on the js thread, to capture the js runtime. Main thread is put to sleep.
* Js thread executes "runtime capture block". The runtime is captured for the main thread. The js thread is put to sleep.
* Main thread wakes up, noticing that the runtime is captured. It executes its js code with the captured runtime. Then, it releases the runtime, which wakes up the js thread. Both the main and js thread move on to other tasks.

How synchronous js -> main thread calls work:
* Js thread puts a ui block on the main queue.
* Js thread goes to sleep until that ui block executes on the main thread.

## Deadlock facebook#1
**Main thread**: execute js now:
  * Main thread puts a block on the js queue, to capture the runtime.
 * Main thread then then goes to sleep, waiting for runtime to be captured

**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep, waiting for that block to execute.

**Result:** The application deadlocks

| {F1978009555} |  {F1978009612} |

![image](https://github.com/user-attachments/assets/325a62f4-d5b7-492d-a114-efb738556239)

## Deadlock facebook#2
**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep waiting for that block to execute.

**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime to be captured

**Result:** The application deadlocks

|  {F1978009690}  | {F1978009701} |

![image](https://github.com/user-attachments/assets/13a6ea17-a55d-453d-9291-d1c8007ecffa)

# Changes
This diff attempts to fix those deadlocks. How:
* In "execute ui code synchronously" (js thread):
   * Before going to sleep, the js thread schedules the ui work on the main queue, **and** it  posts the ui work to "execute js now".
* In "execute js now" (main thread):
   * This diff makes "execute js now" stateful: it keeps a "pending ui block."
   * Before capturing the runtime, the "execute js now" executes "pending ui work", if it exists.
   * While sleeping waiting for runtime capture, "execute js now" can wake up, and execute "pending ui work." It goes back to sleep afterwards, waiting for runtime capture.

## Mitigation: Deadlock facebook#1
**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime capture

**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

The main thread wakes up in "execute js now":
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block." The block, also scheduled on the main thread, noops henceforth.
* Main thread goes back to sleep, waiting for runtime capture.
* The js thread wakes up, moves on to the next task.

**Result:** The runtime is captured by the main thread.

| {F1978010383} | {F1978010363} |  {F1978010371} |  {F1978010379} |

![image](https://github.com/user-attachments/assets/f53cb10c-7801-46be-934a-96af7d5f5fab)

## Mitigation: Deadlock facebook#2
**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

**Main thread**: execute js now
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block" immediately. The block, also scheduled on the main thread, noops henceforth.
* Js thread wakes up and moves onto the next task.

**Result:** Main thread captures the runtime.

|  {F1978010525}  |  {F1978010533} |  {F1978010542} |

![image](https://github.com/user-attachments/assets/9e0ca5ef-fab6-4a26-bcca-d79d36624d5d)

Changelog: [Internal]

Reviewed By: javache

Differential Revision: D74769326
RSNara added a commit to RSNara/react-native that referenced this pull request Jun 13, 2025
Summary:
Pull Request resolved: facebook#51425

# Problem

React native's new architecture will allow components to do sync render/events. That means they'll makes synchronous dispatches from main thread to the js thread, to capture the runtime so that they can execute js on the main thread.

But, the js thread already as a bunch of synchronous calls to the main thread. So, if any of those js -> ui sync calls happen concurrently with a synchronous render, the application will deadlock.

This diff is an attempt to mitigate all those deadlocks.

## Context
How js execution from the main thread works:

* Main thread puts a block on the js thread, to capture the js runtime. Main thread is put to sleep.
* Js thread executes "runtime capture block". The runtime is captured for the main thread. The js thread is put to sleep.
* Main thread wakes up, noticing that the runtime is captured. It executes its js code with the captured runtime. Then, it releases the runtime, which wakes up the js thread. Both the main and js thread move on to other tasks.

How synchronous js -> main thread calls work:
* Js thread puts a ui block on the main queue.
* Js thread goes to sleep until that ui block executes on the main thread.

## Deadlock facebook#1
**Main thread**: execute js now:
  * Main thread puts a block on the js queue, to capture the runtime.
 * Main thread then then goes to sleep, waiting for runtime to be captured

**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep, waiting for that block to execute.

**Result:** The application deadlocks

| {F1978009555} |  {F1978009612} |

![image](https://github.com/user-attachments/assets/325a62f4-d5b7-492d-a114-efb738556239)

## Deadlock facebook#2
**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep waiting for that block to execute.

**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime to be captured

**Result:** The application deadlocks

|  {F1978009690}  | {F1978009701} |

![image](https://github.com/user-attachments/assets/13a6ea17-a55d-453d-9291-d1c8007ecffa)

# Changes
This diff attempts to fix those deadlocks. How:
* In "execute ui code synchronously" (js thread):
   * Before going to sleep, the js thread schedules the ui work on the main queue, **and** it  posts the ui work to "execute js now".
* In "execute js now" (main thread):
   * This diff makes "execute js now" stateful: it keeps a "pending ui block."
   * Before capturing the runtime, the "execute js now" executes "pending ui work", if it exists.
   * While sleeping waiting for runtime capture, "execute js now" can wake up, and execute "pending ui work." It goes back to sleep afterwards, waiting for runtime capture.

## Mitigation: Deadlock facebook#1
**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime capture

**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

The main thread wakes up in "execute js now":
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block." The block, also scheduled on the main thread, noops henceforth.
* Main thread goes back to sleep, waiting for runtime capture.
* The js thread wakes up, moves on to the next task.

**Result:** The runtime is captured by the main thread.

| {F1978010383} | {F1978010363} |  {F1978010371} |  {F1978010379} |

![image](https://github.com/user-attachments/assets/f53cb10c-7801-46be-934a-96af7d5f5fab)

## Mitigation: Deadlock facebook#2
**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

**Main thread**: execute js now
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block" immediately. The block, also scheduled on the main thread, noops henceforth.
* Js thread wakes up and moves onto the next task.

**Result:** Main thread captures the runtime.

|  {F1978010525}  |  {F1978010533} |  {F1978010542} |

![image](https://github.com/user-attachments/assets/9e0ca5ef-fab6-4a26-bcca-d79d36624d5d)

Changelog: [Internal]

Reviewed By: javache

Differential Revision: D74769326
facebook-github-bot pushed a commit that referenced this pull request Jun 13, 2025
Summary:
Pull Request resolved: #51425

# Problem

React native's new architecture will allow components to do sync render/events. That means they'll makes synchronous dispatches from main thread to the js thread, to capture the runtime so that they can execute js on the main thread.

But, the js thread already as a bunch of synchronous calls to the main thread. So, if any of those js -> ui sync calls happen concurrently with a synchronous render, the application will deadlock.

This diff is an attempt to mitigate all those deadlocks.

## Context
How js execution from the main thread works:

* Main thread puts a block on the js thread, to capture the js runtime. Main thread is put to sleep.
* Js thread executes "runtime capture block". The runtime is captured for the main thread. The js thread is put to sleep.
* Main thread wakes up, noticing that the runtime is captured. It executes its js code with the captured runtime. Then, it releases the runtime, which wakes up the js thread. Both the main and js thread move on to other tasks.

How synchronous js -> main thread calls work:
* Js thread puts a ui block on the main queue.
* Js thread goes to sleep until that ui block executes on the main thread.

## Deadlock #1
**Main thread**: execute js now:
  * Main thread puts a block on the js queue, to capture the runtime.
 * Main thread then then goes to sleep, waiting for runtime to be captured

**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep, waiting for that block to execute.

**Result:** The application deadlocks

| {F1978009555} |  {F1978009612} |

![image](https://github.com/user-attachments/assets/325a62f4-d5b7-492d-a114-efb738556239)

## Deadlock #2
**JS thread**: execute ui code synchronously:
* Js thread schedules a block on the ui thread
* Js thread then goes to sleep waiting for that block to execute.

**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime to be captured

**Result:** The application deadlocks

|  {F1978009690}  | {F1978009701} |

![image](https://github.com/user-attachments/assets/13a6ea17-a55d-453d-9291-d1c8007ecffa)

# Changes
This diff attempts to fix those deadlocks. How:
* In "execute ui code synchronously" (js thread):
   * Before going to sleep, the js thread schedules the ui work on the main queue, **and** it  posts the ui work to "execute js now".
* In "execute js now" (main thread):
   * This diff makes "execute js now" stateful: it keeps a "pending ui block."
   * Before capturing the runtime, the "execute js now" executes "pending ui work", if it exists.
   * While sleeping waiting for runtime capture, "execute js now" can wake up, and execute "pending ui work." It goes back to sleep afterwards, waiting for runtime capture.

## Mitigation: Deadlock #1
**Main thread**: execute js now:
* Main thread puts a block on the js queue, to capture the runtime.
* Main thread then then goes to sleep, waiting for runtime capture

**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

The main thread wakes up in "execute js now":
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block." The block, also scheduled on the main thread, noops henceforth.
* Main thread goes back to sleep, waiting for runtime capture.
* The js thread wakes up, moves on to the next task.

**Result:** The runtime is captured by the main thread.

| {F1978010383} | {F1978010363} |  {F1978010371} |  {F1978010379} |

![image](https://github.com/user-attachments/assets/f53cb10c-7801-46be-934a-96af7d5f5fab)

## Mitigation: Deadlock #2
**JS Thread**: execute ui code synchronously:
* Js thread puts its ui block on the ui queue.
* ***New***: Js thread also posts that ui block to "execute js now". Main thread was sleeping waiting for runtime to be captured. It now wakes up.
* Js thread goes to sleep.

**Main thread**: execute js now
* Main thread sees that a "pending ui block" is posted. It executes the "pending ui block" immediately. The block, also scheduled on the main thread, noops henceforth.
* Js thread wakes up and moves onto the next task.

**Result:** Main thread captures the runtime.

|  {F1978010525}  |  {F1978010533} |  {F1978010542} |

![image](https://github.com/user-attachments/assets/9e0ca5ef-fab6-4a26-bcca-d79d36624d5d)

Changelog: [Internal]

Reviewed By: javache

Differential Revision: D74769326

fbshipit-source-id: 854b83ce4e482a4030dc711834ea6c5613091537
RSNara added a commit to RSNara/react-native that referenced this pull request Jul 17, 2025
Summary:
If a native module spec declares a custom type:

https://www.internalfb.com/code/fbsource/[f6aeb413dbc3]/xplat/js/RKJSModules/Libraries/hsr/tm/code/editable_object/NativeEditableObjectModule.js?lines=151-154

The codegen will generate a c++ struct for that type, like so:

```
template <typename P0, typename P1>
struct NativeEditableObjectModuleChangedProperty {
  P0 propertyPath;
  P1 value;

  bool operator==(const NativeEditableObjectModuleChangedProperty &other) const {
    return propertyPath == other.propertyPath && value == other.value;
  }
};
```

## Problem
People can sometimes forget to default initialize this struct:
- **Report:** [post](https://fb.workplace.com/groups/rn.support/permalink/28506993098922601/)
- **Diff facebook#1:** D74868762
- **Diff facebook#2:** D77182083


In this scenario, all the members contain garbage data.

## Changes
This diff ensures that all the members are always default initialized, like so:

```
template <typename P0, typename P1>
struct NativeEditableObjectModuleChangedProperty {
  P0 propertyPath{};
  P1 value{};

  bool operator==(const NativeEditableObjectModuleChangedProperty &other) const {
    return propertyPath == other.propertyPath && value == other.value;
  }
};
```

This way, even if you forget to default initailize the struct, the members will still be default initialized.

## Concerns/Risks
This could cause compilation issues in some of our existing native modules. (if one of the member types doesn't have a default constructor).

Code could start behaving differently, now that all the members are default initialized. (my hunch is that the risk from this causing a problem is low).

Changelog: [General][Changed] c++ tm codegen: Default initialize properties in custom structs

Reviewed By: christophpurrer

Differential Revision: D77315742
RSNara added a commit to RSNara/react-native that referenced this pull request Jul 17, 2025
Summary:
If a native module spec declares a custom type:

https://www.internalfb.com/code/fbsource/[f6aeb413dbc3]/xplat/js/RKJSModules/Libraries/hsr/tm/code/editable_object/NativeEditableObjectModule.js?lines=151-154

The codegen will generate a c++ struct for that type, like so:

```
template <typename P0, typename P1>
struct NativeEditableObjectModuleChangedProperty {
  P0 propertyPath;
  P1 value;

  bool operator==(const NativeEditableObjectModuleChangedProperty &other) const {
    return propertyPath == other.propertyPath && value == other.value;
  }
};
```

## Problem
People can sometimes forget to default initialize this struct:
- **Report:** [post](https://fb.workplace.com/groups/rn.support/permalink/28506993098922601/)
- **Diff facebook#1:** D74868762
- **Diff facebook#2:** D77182083


In this scenario, all the members contain garbage data.

## Changes
This diff ensures that all the members are always default initialized, like so:

```
template <typename P0, typename P1>
struct NativeEditableObjectModuleChangedProperty {
  P0 propertyPath{};
  P1 value{};

  bool operator==(const NativeEditableObjectModuleChangedProperty &other) const {
    return propertyPath == other.propertyPath && value == other.value;
  }
};
```

This way, even if you forget to default initailize the struct, the members will still be default initialized.

## Concerns/Risks
This could cause compilation issues in some of our existing native modules. (if one of the member types doesn't have a default constructor).

Code could start behaving differently, now that all the members are default initialized. (my hunch is that the risk from this causing a problem is low).

Changelog: [General][Changed] c++ tm codegen: Default initialize properties in custom structs

Reviewed By: christophpurrer

Differential Revision: D77315742
RSNara added a commit to RSNara/react-native that referenced this pull request Jul 17, 2025
Summary:
If a native module spec declares a custom type:

https://www.internalfb.com/code/fbsource/[f6aeb413dbc3]/xplat/js/RKJSModules/Libraries/hsr/tm/code/editable_object/NativeEditableObjectModule.js?lines=151-154

The codegen will generate a c++ struct for that type, like so:

```
template <typename P0, typename P1>
struct NativeEditableObjectModuleChangedProperty {
  P0 propertyPath;
  P1 value;

  bool operator==(const NativeEditableObjectModuleChangedProperty &other) const {
    return propertyPath == other.propertyPath && value == other.value;
  }
};
```

## Problem
People can sometimes forget to default initialize this struct:
- **Report:** [post](https://fb.workplace.com/groups/rn.support/permalink/28506993098922601/)
- **Diff facebook#1:** D74868762
- **Diff facebook#2:** D77182083

In this scenario, all the members contain garbage data.

## Changes
This diff ensures that all the members are always default initialized, like so:

```
template <typename P0, typename P1>
struct NativeEditableObjectModuleChangedProperty {
  P0 propertyPath{};
  P1 value{};

  bool operator==(const NativeEditableObjectModuleChangedProperty &other) const {
    return propertyPath == other.propertyPath && value == other.value;
  }
};
```

This way, even if you forget to default initailize the struct, the members will still be default initialized.

## Concerns/Risks
This could cause compilation issues in some of our existing native modules. (if one of the member types doesn't have a default constructor).

Code could start behaving differently, now that all the members are default initialized. (my hunch is that the risk from this causing a problem is low).

Changelog: [General][Changed] c++ tm codegen: Default initialize properties in custom structs

Reviewed By: christophpurrer

Differential Revision: D77315742
gabrieldonadel pushed a commit to gabrieldonadel/react-native that referenced this pull request Aug 12, 2025
Summary:
When running the tests associated with `RNTestPods` with `TSan` enabled, I get a data race:

```
WARNING: ThreadSanitizer: data race (pid=28047)
  Read of size 1 at 0x000144c30be9 by thread T32:
    #0 -[RCTDeviceInfo invalidate] <null> (RNTesterUnitTests:arm64+0x434bf8)
    facebook#1 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ <null> (CoreFoundation:arm64+0x5e7fc)
    facebook#2 decltype(std::declval<void () block_pointer __strong&>()()) std::__1::__invoke[abi:de180100]<void () block_pointer __strong&>(&&, decltype(std::declval<void () block_pointer __strong&>()())&&...) <null> (RNTesterUnitTests:arm64+0x2a19d4)
    facebook#3 std::__1::__function::__func<void () block_pointer __strong, std::__1::allocator<std::__1::allocator>, void ()>::operator()() <null> (RNTesterUnitTests:arm64+0x2a16ec)
    facebook#4 std::__1::__function::__value_func<void ()>::operator()[abi:de180100]() const <null> (RNTesterUnitTests:arm64+0x2455d4)
    facebook#5 std::__1::function<void ()>::operator()() const <null> (RNTesterUnitTests:arm64+0x245404)
    facebook#6 facebook::react::tryAndReturnError(std::__1::function<void ()> const&) <null> (RNTesterUnitTests:arm64+0x2c85b4)
    facebook#7 -[RCTCxxBridge _tryAndHandleError:] <null> (RNTesterUnitTests:arm64+0x27c9e8)
    facebook#8 __NSThreadPerformPerform <null> (Foundation:arm64+0x76c5e8)
    facebook#9 __NSThread__start__ <null> (Foundation:arm64+0x76c27c)

  Previous write of size 1 at 0x000144c30be9 by thread T30:
    #0 -[RCTDeviceInfo invalidate] <null> (RNTesterUnitTests:arm64+0x434c1c)
    facebook#1 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ <null> (CoreFoundation:arm64+0x5e7fc)
    facebook#2 decltype(std::declval<void () block_pointer __strong&>()()) std::__1::__invoke[abi:de180100]<void () block_pointer __strong&>(&&, decltype(std::declval<void () block_pointer __strong&>()())&&...) <null> (RNTesterUnitTests:arm64+0x2a19d4)
    facebook#3 std::__1::__function::__func<void () block_pointer __strong, std::__1::allocator<std::__1::allocator>, void ()>::operator()() <null> (RNTesterUnitTests:arm64+0x2a16ec)
    facebook#4 std::__1::__function::__value_func<void ()>::operator()[abi:de180100]() const <null> (RNTesterUnitTests:arm64+0x2455d4)
    facebook#5 std::__1::function<void ()>::operator()() const <null> (RNTesterUnitTests:arm64+0x245404)
    facebook#6 facebook::react::tryAndReturnError(std::__1::function<void ()> const&) <null> (RNTesterUnitTests:arm64+0x2c85b4)
    facebook#7 -[RCTCxxBridge _tryAndHandleError:] <null> (RNTesterUnitTests:arm64+0x27c9e8)
    facebook#8 __NSThreadPerformPerform <null> (Foundation:arm64+0x76c5e8)
    facebook#9 __NSThread__start__ <null> (Foundation:arm64+0x76c27c)

  Location is heap block of size 48 at 0x000144c30bd0 allocated by main thread:
    #0 calloc <null> (libclang_rt.tsan_iossim_dynamic.dylib:arm64+0x53b90)
    facebook#1 _malloc_type_calloc_outlined <null> (libsystem_malloc.dylib:arm64+0xf8dc)
    facebook#2 -[RCTModuleData setUpInstanceAndBridge:] <null> (RNTesterUnitTests:arm64+0x32715c)
    facebook#3 __25-[RCTModuleData instance]_block_invoke <null> (RNTesterUnitTests:arm64+0x32a288)
    facebook#4 RCTUnsafeExecuteOnMainQueueSync <null> (RNTesterUnitTests:arm64+0x3d6e1c)
    facebook#5 -[RCTModuleData instance] <null> (RNTesterUnitTests:arm64+0x329d78)
    facebook#6 __49-[RCTCxxBridge _prepareModulesWithDispatchGroup:]_block_invoke <null> (RNTesterUnitTests:arm64+0x287e74)
    facebook#7 __wrap_dispatch_group_async_block_invoke <null> (libclang_rt.tsan_iossim_dynamic.dylib:arm64+0x7cffc)
    facebook#8 _dispatch_client_callout <null> (libdispatch.dylib:arm64+0x3c04)
    facebook#9 __70-[XCTestCase _shouldContinueAfterPerformingSetUpSequenceWithSelector:]_block_invoke.136 <null> (XCTestCore:arm64+0x2d068)

  Thread T32 (tid=4154385, running) created by main thread at:
    #0 pthread_create <null> (libclang_rt.tsan_iossim_dynamic.dylib:arm64+0x3027c)
    facebook#1 -[NSThread startAndReturnError:] <null> (Foundation:arm64+0x76bec4)
    facebook#2 -[RCTBridge setUp] <null> (RNTesterUnitTests:arm64+0x23d638)
    facebook#3 -[RCTBridge initWithDelegate:bundleURL:moduleProvider:launchOptions:] <null> (RNTesterUnitTests:arm64+0x23addc)
    facebook#4 -[RCTBridge initWithBundleURL:moduleProvider:launchOptions:] <null> (RNTesterUnitTests:arm64+0x23aa4c)
    facebook#5 -[RCTImageLoaderTests testImageLoaderUsesImageDecoderWithHighestPriority] <null> (RNTesterUnitTests:arm64+0xc578)
    facebook#6 __invoking___ <null> (CoreFoundation:arm64+0x132cdc)

  Thread T30 (tid=4154383, running) created by main thread at:
    #0 pthread_create <null> (libclang_rt.tsan_iossim_dynamic.dylib:arm64+0x3027c)
    facebook#1 -[NSThread startAndReturnError:] <null> (Foundation:arm64+0x76bec4)
    facebook#2 -[RCTBridge setUp] <null> (RNTesterUnitTests:arm64+0x23d638)
    facebook#3 -[RCTBridge initWithDelegate:bundleURL:moduleProvider:launchOptions:] <null> (RNTesterUnitTests:arm64+0x23addc)
    facebook#4 -[RCTBridge initWithBundleURL:moduleProvider:launchOptions:] <null> (RNTesterUnitTests:arm64+0x23aa4c)
    facebook#5 -[RCTImageLoaderTests testImageDecoding] <null> (RNTesterUnitTests:arm64+0xa8d0)
    facebook#6 __invoking___ <null> (CoreFoundation:arm64+0x132cdc)
```

The proposed solution is making the `BOOL` ivar in question a `std::atomic<BOOL>` instead.

## Changelog:

[IOS][FIXED] Data race related to read/write of RCTDeviceInfo._invalidated.

Pull Request resolved: facebook#48890

Test Plan: Existing tests in `RNTesterPods` and manually running RNTester application.

Reviewed By: christophpurrer

Differential Revision: D68629011

Pulled By: javache

fbshipit-source-id: 229d0db4aa13253b96ce0a20c9795c17e344cfc1
gabrieldonadel pushed a commit to gabrieldonadel/react-native that referenced this pull request Aug 12, 2025
…cebook#48496)

Summary:
The reason is when light/dark mode changed, the `hash` value also changed because we used `color.getColor()`. leads to size balanced break.

```
Assertion failed: (index_.size() == lru_.size()), function size, file EvictingCacheMap.h, line 439.

(lldb) bt
* thread facebook#1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
    frame #0: 0x00000001089a9108 libsystem_kernel.dylib`__pthread_kill + 8
    frame facebook#1: 0x0000000105de3408 libsystem_pthread.dylib`pthread_kill + 256
    frame facebook#2: 0x000000018016c4ec libsystem_c.dylib`abort + 104
    frame facebook#3: 0x000000018016b934 libsystem_c.dylib`__assert_rtn + 268
  * frame facebook#4: 0x00000001073e386c React_FabricComponents`folly::EvictingCacheMap<facebook::react::AttributedString, std::__1::shared_ptr<void>, folly::HeterogeneousAccessHash<facebook::react::AttributedString, void>, folly::HeterogeneousAccessEqualTo<facebook::react::AttributedString, void>>::size(this=0x0000600003900348) const at EvictingCacheMap.h:439:5
    frame facebook#5: 0x00000001073e34f4 React_FabricComponents`void folly::EvictingCacheMap<facebook::react::AttributedString, std::__1::shared_ptr<void>, folly::HeterogeneousAccessHash<facebook::react::AttributedString, void>, folly::HeterogeneousAccessEqualTo<facebook::react::AttributedString, void>>::setImpl<facebook::react::AttributedString>(this=0x0000600003900348, key=0x000000016b9f20a8, value=nullptr, promote=true, pruneHook=folly::EvictingCacheMap<facebook::react::AttributedString, std::__1::shared_ptr<void>, folly::HeterogeneousAccessHash<facebook::react::AttributedString, void>, folly::HeterogeneousAccessEqualTo<facebook::react::AttributedString, void> >::PruneHookCall @ 0x000000016b9f1cc8) at EvictingCacheMap.h:674:27
    frame facebook#6: 0x00000001073deb88 React_FabricComponents`folly::EvictingCacheMap<facebook::react::AttributedString, std::__1::shared_ptr<void>, folly::HeterogeneousAccessHash<facebook::react::AttributedString, void>, folly::HeterogeneousAccessEqualTo<facebook::react::AttributedString, void>>::set(this=0x0000600003900348, key=0x000000016b9f20a8, value=ptr = 0x60000024ae20 strong=2 weak=1, promote=true, pruneHook=folly::EvictingCacheMap<facebook::react::AttributedString, std::__1::shared_ptr<void>, folly::HeterogeneousAccessHash<facebook::react::AttributedString, void>, folly::HeterogeneousAccessEqualTo<facebook::react::AttributedString, void> >::PruneHookCall @ 0x000000016b9f1d98) at EvictingCacheMap.h:346:5
    frame facebook#7: 0x00000001073d91dc React_FabricComponents`facebook::react::SimpleThreadSafeCache<facebook::react::AttributedString, std::__1::shared_ptr<void>, 256>::get(this=0x0000600003900348, key=0x000000016b9f20a8, generator= Lambda in File RCTTextLayoutManager.mm at Line 337) const at SimpleThreadSafeCache.h:40:12
    frame facebook#8: 0x00000001073d9058 React_FabricComponents`-[RCTTextLayoutManager _nsAttributedStringFromAttributedString:](self=0x0000600003900340, _cmd="_nsAttributedStringFromAttributedString:", attributedString=AttributedString @ 0x000000016b9f20a8) at RCTTextLayoutManager.mm:337:42
    frame facebook#9: 0x00000001073d6378 React_FabricComponents`-[RCTTextLayoutManager drawAttributedString:paragraphAttributes:frame:drawHighlightPath:](self=0x0000600003900340, _cmd="drawAttributedString:paragraphAttributes:frame:drawHighlightPath:", attributedString=AttributedString @ 0x000000016b9f23a8, paragraphAttributes=ParagraphAttributes @ 0x000000016b9f2378, frame=(origin = (x = 0, y = 0), size = (width = 92, height = 21.666748046875)), block=0x00000001061602d0) at RCTTextLayoutManager.mm:73:56
    frame facebook#10: 0x000000010616020c RCTFabric`-[RCTParagraphTextView drawRect:](self=0x000000012beb9dc0, _cmd="drawRect:", rect=(origin = (x = 0, y = 0.000081380208335701809), size = (width = 92, height = 21.666666666666664))) at RCTParagraphComponentView.mm:346:3
    frame facebook#11: 0x0000000186043e60 UIKitCore`-[UIView(CALayerDelegate) drawLayer:inContext:] + 584
    frame facebook#12: 0x000000018af40080 QuartzCore`CABackingStoreUpdate_ + 244
    frame facebook#13: 0x000000018b0bec88 QuartzCore`invocation function for block in CA::Layer::display_() + 108
    frame facebook#14: 0x000000018b0b5524 QuartzCore`-[CALayer _display] + 1596
    frame facebook#15: 0x000000018b0c7e74 QuartzCore`CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 392
    frame facebook#16: 0x000000018affca50 QuartzCore`CA::Context::commit_transaction(CA::Transaction*, double, double*) + 464
    frame facebook#17: 0x000000018b02b260 QuartzCore`CA::Transaction::commit() + 652
    frame facebook#18: 0x000000018b02c7b4 QuartzCore`CA::Transaction::flush_as_runloop_observer(bool) + 68
    frame facebook#19: 0x0000000185ad6c1c UIKitCore`_UIApplicationFlushCATransaction + 48
    frame facebook#20: 0x0000000185a07ccc UIKitCore`__setupUpdateSequence_block_invoke_2 + 352
    frame facebook#21: 0x000000018505d28c UIKitCore`_UIUpdateSequenceRun + 76
    frame facebook#22: 0x0000000185a07670 UIKitCore`schedulerStepScheduledMainSection + 168
    frame facebook#23: 0x0000000185a06aa8 UIKitCore`runloopSourceCallback + 80
    frame facebook#24: 0x000000018041b7c4 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
    frame facebook#25: 0x000000018041b70c CoreFoundation`__CFRunLoopDoSource0 + 172
    frame facebook#26: 0x000000018041ae70 CoreFoundation`__CFRunLoopDoSources0 + 232
    frame facebook#27: 0x00000001804153b4 CoreFoundation`__CFRunLoopRun + 788
    frame facebook#28: 0x0000000180414c24 CoreFoundation`CFRunLoopRunSpecific + 552
    frame facebook#29: 0x000000019020ab10 GraphicsServices`GSEventRunModal + 160
    frame facebook#30: 0x0000000185ad82fc UIKitCore`-[UIApplication _run] + 796
    frame facebook#31: 0x0000000185adc4f4 UIKitCore`UIApplicationMain + 124
    frame facebook#32: 0x0000000104521f68 RNTester.debug.dylib`main(argc=1, argv=0x000000016b9f5af8) at main.m:15:12
    frame facebook#33: 0x00000001045b9410 dyld_sim`start_sim + 20
    frame facebook#34: 0x0000000104796274 dyld`start + 2840
```

## Changelog:

[IOS] [FIXED] - Fabric: Fixes crash of dynamic color when light/dark mode changed

Pull Request resolved: facebook#48496

Test Plan:
RNTester -> PlatformColor example -> changed the dark/light mode  in the system settings -> go back to App and pop and push the PlatformColor example, it would crash:

![Simulator Screen Recording - iPhone 16 - 2025-01-05 at 15 46 08](https://github.com/user-attachments/assets/f6faaf80-ad03-49c6-9a56-b1117bdc2659)

Reviewed By: sammy-SC

Differential Revision: D68157559

Pulled By: cipolleschi

fbshipit-source-id: 01959845b742ce748186d3877b2792f0f9132ff5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants