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

Implement ThreadSafeFunction class #442

Closed
wants to merge 1 commit into from

Conversation

romandev
Copy link
Contributor

@romandev romandev commented Feb 5, 2019

This PR is implementing ThreadSafeFunction class wraps
napi_threadsafe_function features.

FYI, the test files that included in this PR have come from Node.js
repo[1]. They've been rewritten based on C++ and node-addon-api.

Fixes #312.

[1] https://github.com/nodejs/node/tree/master/test/node-api/test_threadsafe_function

@mhdawson
Copy link
Member

mhdawson commented Feb 6, 2019

@gabrielschulhof would be good if you took a look at this one.

Copy link
Contributor

@gabrielschulhof gabrielschulhof left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is still WIP AFAICT.

napi.h Outdated Show resolved Hide resolved
test/threadsafe_function/threadsafe_function.cc Outdated Show resolved Hide resolved
test/threadsafe_function/threadsafe_function.cc Outdated Show resolved Hide resolved
@romandev romandev changed the title [WIP] Implement ThreadSafeFunction class Implement ThreadSafeFunction class Mar 6, 2019
@romandev romandev force-pushed the threadfunction branch 2 times, most recently from a78aff8 to 78b68be Compare March 6, 2019 15:50
@romandev
Copy link
Contributor Author

romandev commented Mar 6, 2019

@gabrielschulhof, @mhdawson PTAL
(If you don't mind, I'd like to push docs update into separated PR because this PR is enough large)

Copy link
Contributor

@KevinEady KevinEady left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should ThreadSafeFunction::New have multiple overloaded methods? According to the docs, async_resource, thread_finalize_data/thread_finalize_cb, and context are optional, so I would think ThreadSafeFunction::New would have overloads allowing me to bypass them.

napi-inl.h Outdated Show resolved Hide resolved
@mhdawson mhdawson mentioned this pull request Mar 11, 2019
4 tasks
@mhdawson
Copy link
Member

@romandev I'm ok with the docs being in a different PR, but I'd prefer if the two were landed together as opposed to landing one without the other. That might make it difficult to do a release as I think we want to have both in place before having the functionality go out in a release.

@KevinEady
Copy link
Contributor

Is there anything I can do to help with this PR? Maybe docs or something? I have taken a look, and have been successfully using @romandev 's fork in my own project now.

@NickNaso
Copy link
Member

@KevinEady maybe you can start writing a draft to document this new api. What do you
think @romandev @mhdawson @gabrielschulhof ?

@KevinEady
Copy link
Contributor

Hi @NickNaso , that sounds good. I have started on the docs, and I noticed this piece of code in the threadsafe_function.cc:

https://github.com/romandev/node-addon-api/blob/78b68bea4845413b9d06c584f8e21aa75e377058/test/threadsafe_function/threadsafe_function.cc#L39

This got me thinking about the context handling, and I noticed that we pass to napi_create_threadsafe_function a FinalizeData for the context. This means that the call_js callback will have this FinalizeData object passed as the context. Is this acceptable behavior?

@KevinEady
Copy link
Contributor

This got me thinking about the context handling, and I noticed that we pass to napi_create_threadsafe_function a FinalizeData for the context. This means that the call_js callback will have this FinalizeData object passed as the context. Is this acceptable behavior?

I'm working on templating the ThreadSafeFunction class with the Context, and a no-Context tsfn will have nullptr_t as the Context type. With this, I can also implement the (currently unimplemented) GetContext(), as well as correctly passing the Context to CallJs callback.

I am also adding overloaded methods for ThreadSafeFunction<Context>::New() for the optional finalizer, data, and context.

If these API changes make sense, then that'll be what I'll document.

@KevinEady
Copy link
Contributor

@KevinEady
Copy link
Contributor

napi-inl.h Outdated
size_t maxQueueSize,
size_t initialThreadCount) {
return New(env, callback, Object(), resourceName, maxQueueSize,
initialThreadCount, nullptr);
Copy link
Contributor

@DuBistKomisch DuBistKomisch Mar 19, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nullptr used here (and elsewhere) is ambiguous so shows up as mismatched types ‘Context*’ and ‘std::nullptr_t’ when the intended overload is considered as a candidate

apparently need an explicitly overload with std::nullptr_t to resolve it, or I suppose cast it

@DuBistKomisch
Copy link
Contributor

Also, the whole thing probably needs to be wrapped in a NAPI_VERSION check, explodes on 10.6 without declaring NAPI_EXPERIMENTAL.

@mhdawson
Copy link
Member

@DuBistKomisch it probably needs a NAPI version 1.4 check instead as I believe the N-API methods it uses are non-experimental and that would check would exclude it from the earlier versions until we have the backports PRs landed.

@mhdawson
Copy link
Member

Although maybe that is what you suggested :)

@DuBistKomisch
Copy link
Contributor

yeah I'm no n-api expert but the node docs page doesn't seem to list a version under these thread safe function methods

@mhdawson
Copy link
Member

hmm, we seem to be missing that info for those methods. I'll look at adding it as they should show as version 4.

@KevinEady
Copy link
Contributor

@romandev will you be implementing a GetContext() function...?

napi-inl.h Outdated Show resolved Hide resolved
napi-inl.h Outdated Show resolved Hide resolved
napi-inl.h Outdated Show resolved Hide resolved
napi-inl.h Outdated Show resolved Hide resolved
@gabrielschulhof gabrielschulhof dismissed their stale review March 25, 2019 21:21

Re-reviewed.

@romandev
Copy link
Contributor Author

@KevinEady If you're already implementing GetContext(), I'll leave a FIXME comment and then you can land your patch in follow-up PR. If you'd like to include the GetContext() implementation in this patch, I'll continue the work. Basically, I wanted to implement GetContext without explicit template. (But I'm not sure if it is possible or not.)

@gabrielschulhof
Copy link
Contributor

@romandev I think if we should throw when one attempts to assign to a non-empty ThreadSafeFunction.

@romandev
Copy link
Contributor Author

@gabrielschulhof, In fact, I already did that here: https://github.com/nodejs/node-addon-api/pull/442/files#diff-f546e4cc35b454813e5264fe9c9e6fc8R3898

However, I think we still need a way to reset the ThreadSafeFunction to empty in ThreadSafeFinalizeCallback if the ThreadSafeFunction is aborted or released.

For example, in the current test, declare ThreadSafeFunction as a static global variable, and assign a new ThreadSafeFunction whenever StartThreadInternal is called. If it's non-empty at this time, it would throw an exception. However, if it's empty (by ThreadSafeFinalizeCallback), we can re-assign a new object again.

If there was no such logic, we would have to have a static ThreadSafeFunction array to create a new ThreadSafeFunction whenever StartThreadInternal is called. (because there would be no way to re-assign a new object) Or, we might need to make a wrapper object for ThreadSafeFunction on heap to maintain creating/destroying the object.

@gabrielschulhof
Copy link
Contributor

@romandev a policy of "You cannot assign to a ThreadSafeFunction until the existing one has finished operating" makes sense to me.

@mhdawson mhdawson mentioned this pull request Jun 24, 2019
KevinEady added a commit to KevinEady/node-addon-api that referenced this pull request Jun 26, 2019
@@ -0,0 +1,185 @@
#include <uv.h>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we want a big comment here that says this using uv is not guaranteed to be ABI stable. That if you want to use the stability guarantee from N-API you need to use other means to implement threads. This is the first example where we have used uv in the testing and we want it to be clear that it is not what we recommend and that we only do it because we know the test suite will be build/run with Node.js as opposed to being built into a binary that will run across different Node.js versions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm ... we could use std::thread instead, right? I think all our supported compilers now have C++11, right? In the test in core I used libuv because, well, we maintain core ourselves, and because in core I seek to keep N-API tests written in C as much as possible. @romandev could you convert this to std::thread?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be better.

Copy link
Member

@mhdawson mhdawson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM after the comment I suggested is added.

@KevinEady
Copy link
Contributor

KevinEady commented Jun 28, 2019 via email

@gabrielschulhof
Copy link
Contributor

... and I'm actually thinking of using C11's thrd_create() in the core N-API test – wanna test though whether it's available on all our supported platforms.

@gabrielschulhof
Copy link
Contributor

Well, it looks like #include <threads.h> doesn't work on all our platforms. Dunno if the STL is in a similar state. Maybe we should hold off on this for now and just bring in the comment from https://github.com/nodejs/node/blob/master/test/node-api/test_threadsafe_function/binding.c#L1-L5

@gabrielschulhof
Copy link
Contributor

@addaleax:

[...] I think C++ std::thread is the easier way to go. That’s in C++11 and should be included everywhere.

@romandev can you please move the test over to std::thread?

@romandev
Copy link
Contributor Author

romandev commented Jul 2, 2019

@romandev can you please move the test over to std::thread?

@gabrielschulhof Done. Thanks.

This PR is implementing ThreadSafeFunction class wraps
napi_threadsafe_function features.

FYI, the test files that included in this PR have come from Node.js
repo[1]. They've been rewritten based on C++ and node-addon-api.

Fixes nodejs#312.

[1] https://github.com/nodejs/node/tree/master/test/node-api/test_threadsafe_function
@romandev
Copy link
Contributor Author

romandev commented Jul 3, 2019

FYI, I got rid of std::make_unique from latest patch because the make_unique() is C++ 14 feature..

@gabrielschulhof
Copy link
Contributor

gabrielschulhof commented Jul 9, 2019

@KevinEady
Copy link
Contributor

Hi @gabrielschulhof ,

Looks like the node-9 tests are failing because the napi tsfn functions don't exist. Were tsfns backported to node 9? Don't see them listed on the n-api docs.

gabrielschulhof pushed a commit that referenced this pull request Jul 10, 2019
This PR is implementing ThreadSafeFunction class wraps
napi_threadsafe_function features.

FYI, the test files that included in this PR have come from Node.js
repo[1]. They've been rewritten based on C++ and node-addon-api.

[1] https://github.com/nodejs/node/tree/e800f9d/test/node-api/test_threadsafe_function

PR-URL: #442
Fixes: #312
Reviewed-By: Michael Dawson <[email protected]>
Reviewed-By: Gabriel Schulhof <[email protected]>
@gabrielschulhof
Copy link
Contributor

Landed in 0a90df2. Thanks @romandev!

kevindavies8 added a commit to kevindavies8/node-addon-api-Develop that referenced this pull request Aug 24, 2022
This PR is implementing ThreadSafeFunction class wraps
napi_threadsafe_function features.

FYI, the test files that included in this PR have come from Node.js
repo[1]. They've been rewritten based on C++ and node-addon-api.

[1] https://github.com/nodejs/node/tree/e800f9d/test/node-api/test_threadsafe_function

PR-URL: nodejs/node-addon-api#442
Fixes: nodejs/node-addon-api#312
Reviewed-By: Michael Dawson <[email protected]>
Reviewed-By: Gabriel Schulhof <[email protected]>
Marlyfleitas added a commit to Marlyfleitas/node-api-addon-Development that referenced this pull request Aug 26, 2022
This PR is implementing ThreadSafeFunction class wraps
napi_threadsafe_function features.

FYI, the test files that included in this PR have come from Node.js
repo[1]. They've been rewritten based on C++ and node-addon-api.

[1] https://github.com/nodejs/node/tree/e800f9d/test/node-api/test_threadsafe_function

PR-URL: nodejs/node-addon-api#442
Fixes: nodejs/node-addon-api#312
Reviewed-By: Michael Dawson <[email protected]>
Reviewed-By: Gabriel Schulhof <[email protected]>
wroy7860 added a commit to wroy7860/addon-api-benchmark-node that referenced this pull request Sep 19, 2022
This PR is implementing ThreadSafeFunction class wraps
napi_threadsafe_function features.

FYI, the test files that included in this PR have come from Node.js
repo[1]. They've been rewritten based on C++ and node-addon-api.

[1] https://github.com/nodejs/node/tree/e800f9d/test/node-api/test_threadsafe_function

PR-URL: nodejs/node-addon-api#442
Fixes: nodejs/node-addon-api#312
Reviewed-By: Michael Dawson <[email protected]>
Reviewed-By: Gabriel Schulhof <[email protected]>
johnfrench3 pushed a commit to johnfrench3/node-addon-api-git that referenced this pull request Aug 11, 2023
This PR is implementing ThreadSafeFunction class wraps
napi_threadsafe_function features.

FYI, the test files that included in this PR have come from Node.js
repo[1]. They've been rewritten based on C++ and node-addon-api.

[1] https://github.com/nodejs/node/tree/e800f9d/test/node-api/test_threadsafe_function

PR-URL: nodejs/node-addon-api#442
Fixes: nodejs/node-addon-api#312
Reviewed-By: Michael Dawson <[email protected]>
Reviewed-By: Gabriel Schulhof <[email protected]>
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.

Support for Asynchronous Thread-safe Function Calls
8 participants