Files
react-native/ReactCommon
Ramanpreet Nara 553729f3d6 Create method queues for NativeModules that neither provide nor request one
Summary:
## Problem:
Let `A` be the set of all ObjC NativeModules that neither provide nor reqeust a method queue.

The TurboModule system dispatches all method calls to NativeModules in `A` synchronously to the JS thread. Here is the relevant logic:

**RCTTurboModule.mm:**
Link: https://fburl.com/diffusion/nz9gqje8
```
jsi::Value performMethodInvocation(
  // ...
)
{
  // ...

  dispatch_queue_t methodQueue = NULL;
  if ([instance_ conformsToProtocol:protocol(RCTBridgeModule)] &&
      [instance_ respondsToSelector:selector(methodQueue)]) {
    methodQueue = [instance_ performSelector:selector(methodQueue)];
  }

  if (methodQueue == NULL || methodQueue == RCTJSThread) {
    // This is the default mode of execution: on JS thread.
    block();
  } else if (methodQueue == dispatch_get_main_queue()) {

```

**Why does this end up happening?**
1. NativeModules that request a method queue have `synthesize methodQueue = _methodQueue` in their `implementation` section. This generates a `methodQueue` getter for the NativeModule, and also creates an ivar to back that getter. The TurboModule system generates a `dispatch_queue_t` and uses ObjC's KVC API to write to the ivar. So in the above logic, for NativeModules that provide a method queue, methodQueue will neither be `NULL` nor `RCTJSThread`, so we don't dispatch synchronously to the JS thread.
2. NativeModules that provide a method queue will return something that is not `NULL` or something that is `RCTJSThread`. If they return `NULL`, the infra will throw an error early. If they return `RCTJSThread`, we'll dispatch synchronously to the JS thread, as we should (...wait. For async NativeModule methods that dispatch to `RCTJSThread`, should we dispatch asynchronously to the JS thread, via jsInvoker? **Edit:** Nope: https://fburl.com/diffusion/ivt9b40s.). In all other cases, we dispatch to appropriately to the respective method queue.
3. For NativeModules that neither provide nor request a method queue (i.e: NativeModules in `A`), they don't implement the `methodQueue` selector. Therefore, we dispatch synchronously to the JS thread.

## The fix (Part 1):
The first step towards fixing this problem is to generate `dispatch_queue_t`s for NativeModules in `A`.

That's what this diff accomplishes.

Changelog:
[iOS][Fixed] - Create method queue for NativeModules that don't provide nor request one.

Reviewed By: fkgozali

Differential Revision: D20821054

fbshipit-source-id: 17a73550ad96766c5c7e719e28e1cc879e36465c
2020-04-03 12:28:43 -07:00
..
2020-04-03 09:47:42 -07:00
2020-04-03 09:47:42 -07:00
2020-02-28 12:46:49 -08:00
2020-02-28 12:46:49 -08:00