已合并
fix: fix a crash caused by removing a NAPI reference on JS thread #1801
gyange创建于 2025年11月11日
fix: fix a crash caused by removing a NAPI reference on JS thread #1801
已合并
共 9 个文件变更+54-21
| @@ -7,8 +7,8 @@ | |||
| 7 | "prepack": "npm i && echo 'when packing actual package run: npm run pack:harmony'", | 7 | "prepack": "npm i && echo 'when packing actual package run: npm run pack:harmony'", |
| 8 | "pack:harmony": "react-native pack-harmony --oh-module-path ../tester/harmony/sample_package --harmony-dir-path ./harmony --package-json-path ./package.json", | 8 | "pack:harmony": "react-native pack-harmony --oh-module-path ../tester/harmony/sample_package --harmony-dir-path ./harmony --package-json-path ./package.json", |
| 9 | "codegen-lib": "react-native codegen-lib-harmony --no-safety-check --npm-package-name react-native-harmony-sample-package-2 --cpp-output-path ../tester/harmony/sample_package/src/main/cpp/generated --ets-output-path ../tester/harmony/sample_package/src/main/ets/generated --cpp-components-spec-paths ./src/specs/codegen-lib/CodegenLibCppSampleNativeComponent.ts --turbo-modules-spec-paths ./src/specs/codegen-lib/NativeCodegenLibSampleModule.ts --arkts-components-spec-paths ./src/specs/codegen-lib/CodegenLibArkTSSampleNativeComponent.ts", | 9 | "codegen-lib": "react-native codegen-lib-harmony --no-safety-check --npm-package-name react-native-harmony-sample-package-2 --cpp-output-path ../tester/harmony/sample_package/src/main/cpp/generated --ets-output-path ../tester/harmony/sample_package/src/main/ets/generated --cpp-components-spec-paths ./src/specs/codegen-lib/CodegenLibCppSampleNativeComponent.ts --turbo-modules-spec-paths ./src/specs/codegen-lib/NativeCodegenLibSampleModule.ts --arkts-components-spec-paths ./src/specs/codegen-lib/CodegenLibArkTSSampleNativeComponent.ts", |
| 10 | - "install:local-cli": "cd ../react-native-harmony-cli && npm pack && cd ../react-native-harmony-sample-package && npm i ../react-native-harmony-cli/rnoh-react-native-harmony-cli-0.0.26.tgz", | 10 | + "install:local-cli": "cd ../react-native-harmony-cli && npm pack && cd ../react-native-harmony-sample-package && npm i -D ../react-native-harmony-cli/rnoh-react-native-harmony-cli-0.0.40.tgz", |
| 11 | - "install:rn_harmony": "cd ../react-native-harmony && npm pack && cd ../react-native-harmony-sample-package && npm uninstall react-native-harmony && npm i react-native-harmony@file:../react-native-harmony/rnoh-react-native-harmony-0.72.100.tgz" | 11 | + "install:rn_harmony": "cd ../react-native-harmony && npm pack && cd ../react-native-harmony-sample-package && npm uninstall react-native-harmony && npm i -D react-native-harmony@file:../react-native-harmony/rnoh-react-native-harmony-0.72.100.tgz" |
| 12 | }, | 12 | }, |
| 13 | "keywords": [], | 13 | "keywords": [], |
| 14 | "author": "", | 14 | "author": "", |
| @@ -37,12 +37,14 @@ | |||
| 37 | ], | 37 | ], |
| 38 | "peerDependencies": { | 38 | "peerDependencies": { |
| 39 | "react": "*", | 39 | "react": "*", |
| 40 | - "react-native": "*" | 40 | + "react-native": "*", |
| 41 | + "react-native-harmony": "*" | ||
| 41 | }, | 42 | }, |
| 42 | "devDependencies": { | 43 | "devDependencies": { |
| 43 | - "@rnoh/react-native-harmony-cli": "file:../react-native-harmony-cli/rnoh-react-native-harmony-cli-0.0.40.tgz", | ||
| 44 | "@types/react": "^18.2.47", | 44 | "@types/react": "^18.2.47", |
| 45 | "react": "18.2.0", | 45 | "react": "18.2.0", |
| 46 | + "@rnoh/react-native-harmony-cli": "file:../react-native-harmony-cli/rnoh-react-native-harmony-cli-0.0.40.tgz", | ||
| 47 | + "react-native-harmony": "file:../react-native-harmony/rnoh-react-native-harmony-0.72.100.tgz", | ||
| 46 | "react-native": "0.72.5" | 48 | "react-native": "0.72.5" |
| 47 | } | 49 | } |
| 48 | } | 50 | } |
| @@ -5,13 +5,21 @@ | |||
| 5 | * LICENSE-MIT file in the root directory of this source tree. | 5 | * LICENSE-MIT file in the root directory of this source tree. |
| 6 | */ | 6 | */ |
| 7 | 7 | ||
| 8 | -const { config: harmonyConfig } = require('@rnoh/react-native-harmony-cli') | 8 | +try { |
| 9 | + const { config: harmonyConfig } = require('@rnoh/react-native-harmony-cli'); | ||
| 10 | +} catch (err) { | ||
| 11 | + console.warn( | ||
| 12 | + '[WARNING] react-native-harmony failed to load CLI Config from @rnoh/react-native-harmony-cli. Error message: ', | ||
| 13 | + err?.message | ||
| 14 | + ); | ||
| 15 | + throw err; | ||
| 16 | +} | ||
| 9 | 17 | ||
| 10 | /** | 18 | /** |
| 11 | * @type {import("@react-native-community/cli-types").Config} | 19 | * @type {import("@react-native-community/cli-types").Config} |
| 12 | */ | 20 | */ |
| 13 | const config = { | 21 | const config = { |
| 14 | commands: harmonyConfig.commands, | 22 | commands: harmonyConfig.commands, |
| 15 | -} | 23 | +}; |
| 16 | 24 | ||
| 17 | -module.exports = config | 25 | +module.exports = config; |
| @@ -1 +0,0 @@ | |||
| 1 | -18 | ||
| @@ -26,7 +26,25 @@ class MountingManager { | |||
| 26 | 26 | ||
| 27 | public: | 27 | public: |
| 28 | using Shared = std::shared_ptr<MountingManager>; | 28 | using Shared = std::shared_ptr<MountingManager>; |
| 29 | - using Weak = std::weak_ptr<MountingManager>; | 29 | + class Weak { |
这里的修改是否会产生非兼容变更? ![]() ![]() | |||
| 30 | + public: | ||
| 31 | + Weak() = default; | ||
| 32 | + explicit Weak( | ||
| 33 | + std::weak_ptr<MountingManager> weakPtr, | ||
| 34 | + std::weak_ptr<std::atomic<bool>> willBeDestroyed) | ||
| 35 | + : m_weakPtr(weakPtr), m_willBeDestroyed(willBeDestroyed) {} | ||
| 36 | + | ||
| 37 | + std::shared_ptr<MountingManager> lock() const noexcept { | ||
| 38 | + auto willBeDestroyed = m_willBeDestroyed.lock(); | ||
| 39 | + if (!willBeDestroyed || willBeDestroyed->load()) { | ||
| 40 | + return nullptr; | ||
| 41 | + } | ||
| 42 | + return m_weakPtr.lock(); | ||
| 43 | + } | ||
| 44 | + private: | ||
| 45 | + std::weak_ptr<MountingManager> m_weakPtr; | ||
| 46 | + std::weak_ptr<std::atomic<bool>> m_willBeDestroyed; | ||
| 47 | + }; | ||
| 30 | 48 | ||
| 31 | virtual ~MountingManager() noexcept = default; | 49 | virtual ~MountingManager() noexcept = default; |
| 32 | 50 | ||
| @@ -60,7 +78,9 @@ class MountingManager { | |||
| 60 | facebook::react::ComponentDescriptor const& componentDescriptor) = 0; | 78 | facebook::react::ComponentDescriptor const& componentDescriptor) = 0; |
| 61 | 79 | ||
| 62 | virtual void clearPreallocatedViews() = 0; | 80 | virtual void clearPreallocatedViews() = 0; |
| 63 | - virtual void clearPreallocatedViews(facebook::react::ShadowViewMutationList mutations) = 0; | 81 | + |
| 82 | + virtual void clearPreallocatedViews( | ||
| 83 | + facebook::react::ShadowViewMutationList mutations) = 0; | ||
| 64 | virtual void clearPreallocationRequestQueue() = 0; | 84 | virtual void clearPreallocationRequestQueue() = 0; |
| 65 | }; | 85 | }; |
| 66 | } // namespace rnoh | 86 | } // namespace rnoh |
| @@ -22,7 +22,6 @@ | |||
| 22 | 22 | ||
| 23 | 23 | ||
| 24 | 24 | ||
| 25 | - | ||
| 26 | 25 | ||
| 27 | using namespace facebook; | 26 | using namespace facebook; |
| 28 | using namespace rnoh; | 27 | using namespace rnoh; |
| @@ -46,7 +45,7 @@ void RNInstanceArkTS::start() { | |||
| 46 | } | 45 | } |
| 47 | 46 | ||
| 48 | void RNInstanceArkTS::setJavaScriptExecutorFactory( | 47 | void RNInstanceArkTS::setJavaScriptExecutorFactory( |
| 49 | - std::shared_ptr<facebook::react::JSExecutorFactory> jsExecutorFactory) { | 48 | + std::shared_ptr<facebook::react::JSExecutorFactory> jsExecutorFactory) { |
| 50 | DLOG(INFO) << "RNInstanceArkTS::setJavaScriptExecutorFactory"; | 49 | DLOG(INFO) << "RNInstanceArkTS::setJavaScriptExecutorFactory"; |
| 51 | m_jsExecutorFactory = jsExecutorFactory; | 50 | m_jsExecutorFactory = jsExecutorFactory; |
| 52 | } | 51 | } |
| @@ -107,8 +106,10 @@ void RNInstanceArkTS::initializeScheduler( | |||
| 107 | 106 | ||
| 108 | m_animationDriver = std::make_shared<react::LayoutAnimationDriver>( | 107 | m_animationDriver = std::make_shared<react::LayoutAnimationDriver>( |
| 109 | this->instance->getRuntimeExecutor(), m_contextContainer, this); | 108 | this->instance->getRuntimeExecutor(), m_contextContainer, this); |
| 110 | - m_schedulerDelegate = std::make_unique<rnoh::SchedulerDelegate>( | 109 | + m_schedulerDelegate = std::make_unique<rnoh::SchedulerDelegate>( |
| 111 | - m_mountingManager, taskExecutor, ComponentInstancePreallocationRequestQueue::Weak()); | 110 | + MountingManager::Weak(m_mountingManager, m_isAboutToBeDestroyed), |
| 111 | + taskExecutor, | ||
| 112 | + ComponentInstancePreallocationRequestQueue::Weak()); | ||
| 112 | this->scheduler = std::make_shared<react::Scheduler>( | 113 | this->scheduler = std::make_shared<react::Scheduler>( |
| 113 | schedulerToolbox, m_animationDriver.get(), m_schedulerDelegate.get()); | 114 | schedulerToolbox, m_animationDriver.get(), m_schedulerDelegate.get()); |
| 114 | turboModuleProvider->setScheduler(this->scheduler); | 115 | turboModuleProvider->setScheduler(this->scheduler); |
| @@ -178,8 +179,8 @@ void RNInstanceArkTS::startSurface( | |||
| 178 | surfaceHandler->setProps(std::move(initialProps)); | 179 | surfaceHandler->setProps(std::move(initialProps)); |
| 179 | auto layoutConstraints = surfaceHandler->getLayoutConstraints(); | 180 | auto layoutConstraints = surfaceHandler->getLayoutConstraints(); |
| 180 | layoutConstraints.layoutDirection = react::LayoutDirection::LeftToRight; | 181 | layoutConstraints.layoutDirection = react::LayoutDirection::LeftToRight; |
| 181 | - layoutConstraints.minimumSize = | 182 | + layoutConstraints.minimumSize = layoutConstraints.maximumSize = { |
| 182 | - layoutConstraints.maximumSize = {.width = maxWidth, .height = maxHeight}; | 183 | + .width = maxWidth, .height = maxHeight}; |
| 183 | auto layoutContext = surfaceHandler->getLayoutContext(); | 184 | auto layoutContext = surfaceHandler->getLayoutContext(); |
| 184 | layoutContext.viewportOffset = {viewportOffsetX, viewportOffsetY}; | 185 | layoutContext.viewportOffset = {viewportOffsetX, viewportOffsetY}; |
| 185 | layoutContext.pointScaleFactor = pixelRatio; | 186 | layoutContext.pointScaleFactor = pixelRatio; |
| @@ -161,7 +161,7 @@ void RNInstanceCAPI::initializeScheduler( | |||
| 161 | m_animationDriver = std::make_shared<react::LayoutAnimationDriver>( | 161 | m_animationDriver = std::make_shared<react::LayoutAnimationDriver>( |
| 162 | this->instance->getRuntimeExecutor(), m_contextContainer, this); | 162 | this->instance->getRuntimeExecutor(), m_contextContainer, this); |
| 163 | m_schedulerDelegate = std::make_unique<rnoh::SchedulerDelegate>( | 163 | m_schedulerDelegate = std::make_unique<rnoh::SchedulerDelegate>( |
| 164 | - m_mountingManager, | 164 | + MountingManager::Weak(m_mountingManager, m_isAboutToBeDestroyed), |
| 165 | this->taskExecutor, | 165 | this->taskExecutor, |
| 166 | m_componentInstancePreallocationRequestQueue); | 166 | m_componentInstancePreallocationRequestQueue); |
| 167 | this->scheduler = std::make_shared<react::Scheduler>( | 167 | this->scheduler = std::make_shared<react::Scheduler>( |
| @@ -27,15 +27,17 @@ class SchedulerDelegate final : public facebook::react::SchedulerDelegate { | |||
| 27 | using ShadowNode = facebook::react::ShadowNode; | 27 | using ShadowNode = facebook::react::ShadowNode; |
| 28 | using ShadowView = facebook::react::ShadowView; | 28 | using ShadowView = facebook::react::ShadowView; |
| 29 | using SurfaceId = facebook::react::SurfaceId; | 29 | using SurfaceId = facebook::react::SurfaceId; |
| 30 | - using PreallocationRequest = ComponentInstancePreallocationRequestQueue::Request; | 30 | + using PreallocationRequest = |
| 31 | + ComponentInstancePreallocationRequestQueue::Request; | ||
| 31 | 32 | ||
| 32 | public: | 33 | public: |
| 33 | SchedulerDelegate( | 34 | SchedulerDelegate( |
| 34 | - MountingManager::Shared mountingManager, | 35 | + MountingManager::Weak mountingManager, |
| 35 | TaskExecutor::Shared taskExecutor, | 36 | TaskExecutor::Shared taskExecutor, |
| 36 | ComponentInstancePreallocationRequestQueue::Weak | 37 | ComponentInstancePreallocationRequestQueue::Weak |
| 37 | weakPreallocationRequestQueue) | 38 | weakPreallocationRequestQueue) |
| 38 | - : m_mountingManager(mountingManager), m_taskExecutor(taskExecutor), | 39 | + : m_mountingManager(std::move(mountingManager)), |
| 40 | + m_taskExecutor(taskExecutor), | ||
| 39 | m_weakPreallocationRequestQueue( | 41 | m_weakPreallocationRequestQueue( |
| 40 | std::move(weakPreallocationRequestQueue)){}; | 42 | std::move(weakPreallocationRequestQueue)){}; |
| 41 | 43 | ||
| @@ -45,7 +47,6 @@ class SchedulerDelegate final : public facebook::react::SchedulerDelegate { | |||
| 45 | 47 | ||
| 46 | void schedulerDidFinishTransaction( | 48 | void schedulerDidFinishTransaction( |
| 47 | MountingCoordinator::Shared mountingCoordinator) override; | 49 | MountingCoordinator::Shared mountingCoordinator) override; |
| 48 | - | ||
| 49 | 50 | ||
| 50 | void schedulerDidDispatchCommand( | 51 | void schedulerDidDispatchCommand( |
| 51 | const ShadowView& shadowView, | 52 | const ShadowView& shadowView, |
| @@ -55,6 +55,7 @@ | |||
| 55 | "@react-native-community/eslint-config": "^3.2.0", | 55 | "@react-native-community/eslint-config": "^3.2.0", |
| 56 | "@react-native/eslint-config": "^0.74.0", | 56 | "@react-native/eslint-config": "^0.74.0", |
| 57 | "@react-native/metro-config": "^0.72.6", | 57 | "@react-native/metro-config": "^0.72.6", |
| 58 | + "@rnoh/react-native-harmony-cli": "file:../react-native-harmony-cli/rnoh-react-native-harmony-cli-0.0.40.tgz", | ||
| 58 | "@rnoh/testerino": "file:../rnoh-testerino-0.0.9.tgz", | 59 | "@rnoh/testerino": "file:../rnoh-testerino-0.0.9.tgz", |
| 59 | "@tsconfig/react-native": "^2.0.2", | 60 | "@tsconfig/react-native": "^2.0.2", |
| 60 | "@types/chai": "^4.3.4", | 61 | "@types/chai": "^4.3.4", |


【建议】【基本代码】【日志输出问题】异常日志等级是否使用error