Skip to content
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

Fix: await device.lost hangs when called before device.destroy() #129

Open
wants to merge 36 commits into
base: main
Choose a base branch
from

Conversation

hmallen99
Copy link

@hmallen99 hmallen99 commented Sep 24, 2024

Resolves #126

Problem

Fixes a bug where javascript promises will hang the main thread while waiting for an std::future value on the native side. In the case of await device.lost, this causes the main thread to hang indefinitely, as device.destroy cannot be called to resolve the promise. This bug was discovered by running the impl against the gpuweb cts.

Solution

  • Updates the conversion from std::future to JS promise to use a more robust async implementation, allowing promises to await on a background thread.
  • Copies the threading code from react-native-nitro-modules, with some logging and debug code stripped out. .hpp files have been converted to .h files and the namespace has been shortened from margelo::nitro -> margelo to match the conventions used in this repo.

Testing

  • Added a unit test in the Device test suite to validate that device.lost will not hang the main thread if device.destroy is not called. With the old threading logic, this test hangs indefinitely. With the new test logic, we are able to cancel the promise.
  • Added a unit test to validate that device.lost resolves if it is awaited before calling device.destroy
  • After doing some more testing against the gpuweb-cts, all of the promise hangs resulted from one of these two scenarios

@wcandillon
Copy link
Owner

@hmallen99 I'm very excited about this.

Right now I'm heads down with some deep Canvas API refactorings but after that I could look into the nitro module migration.

@hmallen99 hmallen99 marked this pull request as ready for review September 25, 2024 16:23
@hmallen99
Copy link
Author

@hmallen99 I'm very excited about this.

Right now I'm heads down with some deep Canvas API refactorings but after that I could look into the nitro module migration.

Migrating to nitro modules would be ideal! I think this should act as a stop-gap until that migration can happen, though.

I've tested this against the conformance test suite, and it removes a lot of the blockers for running the tests. The remaining inventory seems to be around throwing the proper RangeError for incorrect buffer sizes and catching some shader compilation issues. I can file some more issues!

@wcandillon
Copy link
Owner

I agree! Should we jump on a call to discuss how to run CTS with this module? I would love to learn more.

@hmallen99
Copy link
Author

Yes, let's hop on a call @wcandillon! Please let me know how and when you would like to call. The process of running tests requires a bit of setup right now, but I can walk you through some of it. It's fairly similar to running the example app in this repo. I'm hoping to make it more automated in the future, though.

@hmallen99
Copy link
Author

I also updated the README to include build and test instructions in my fork of the cts, if you want to give that a try. It would be useful to have the feedback if those instructions don’t make sense! https://github.com/rebeckerspecialties/gpuweb-cts/blob/main/README.md

@wcandillon
Copy link
Owner

my email is public, can you send me a proposal calendar invite?

@hmallen99
Copy link
Author

my email is public, can you send me a proposal calendar invite?

Sent you an invite!

@hmallen99
Copy link
Author

Hey @wcandillon, are we able to merge this PR? It should be working on both iOS and android with tests passing. Thanks!

@wcandillon
Copy link
Owner

thanks for letting me know, I will start reviewing it.

@hmallen99
Copy link
Author

thanks for letting me know, I will start reviewing it.

Hmm, I'll take a look at the CI failures. Thanks for running the actions!

@wcandillon
Copy link
Owner

@hmallen99 we're on the verge of merging #137, this PR will be next immediately after that 🙏

@hmallen99
Copy link
Author

@hmallen99 we're on the verge of merging #137, this PR will be next immediately after that 🙏

Awesome, I just validated that all the static analysis and test steps are passing locally. I'll validate the build-android and build-ios steps as well.

@wcandillon
Copy link
Owner

@hmallen99 just had a look and it makes sense . Did you try it on Android? I don't think we pass the jsInvoker there.

@wcandillon
Copy link
Owner

@hmallen99 I can fix the android issue for you

@hmallen99
Copy link
Author

@hmallen99 I can fix the android issue for you

Thanks @wcandillon, that would be great! The android simulator seems to run very slowly on my machine, so it's hard for me to debug.

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.

await GPUDevice.lost hangs indefinitely if called before GPUDevice.destroy()
2 participants