Skip to content

Commit

Permalink
Apply formatting changes
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinEady committed Nov 24, 2020
1 parent 559ad8c commit 5e5b9ce
Show file tree
Hide file tree
Showing 9 changed files with 542 additions and 317 deletions.
432 changes: 280 additions & 152 deletions napi-inl.h

Large diffs are not rendered by default.

163 changes: 104 additions & 59 deletions napi.h
Original file line number Diff line number Diff line change
Expand Up @@ -2249,15 +2249,14 @@ namespace Napi {
napi_threadsafe_function _tsfn;
};

// A TypedThreadSafeFunction by default has no context (nullptr) and can accept
// any type (void) to its CallJs.
template <typename ContextType = std::nullptr_t, typename DataType = void,
void (*CallJs)(Napi::Env, Napi::Function, ContextType *,
DataType *) = nullptr>
// A TypedThreadSafeFunction by default has no context (nullptr) and can
// accept any type (void) to its CallJs.
template <typename ContextType = std::nullptr_t,
typename DataType = void,
void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*) =
nullptr>
class TypedThreadSafeFunction {

public:

public:
// This API may only be called from the main thread.
// Helper function that returns nullptr if running N-API 5+, otherwise a
// non-empty, no-op Function. This provides the ability to specify at
Expand All @@ -2268,85 +2267,123 @@ namespace Napi {
#else
static Napi::Function EmptyFunctionFactory(Napi::Env env);
#endif
static Napi::Function FunctionOrEmpty(Napi::Env env, Napi::Function& callback);
static Napi::Function FunctionOrEmpty(Napi::Env env,
Napi::Function& callback);

#if NAPI_VERSION > 4
// This API may only be called from the main thread.
// Creates a new threadsafe function with:
// Callback [missing] Resource [missing] Finalizer [missing]
template <typename ResourceString>
static TypedThreadSafeFunction<ContextType, DataType, CallJs>
New(napi_env env, ResourceString resourceName, size_t maxQueueSize,
size_t initialThreadCount, ContextType *context = nullptr);
static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
napi_env env,
ResourceString resourceName,
size_t maxQueueSize,
size_t initialThreadCount,
ContextType* context = nullptr);

// This API may only be called from the main thread.
// Creates a new threadsafe function with:
// Callback [missing] Resource [passed] Finalizer [missing]
template <typename ResourceString>
static TypedThreadSafeFunction<ContextType, DataType, CallJs>
New(napi_env env, const Object &resource, ResourceString resourceName,
size_t maxQueueSize, size_t initialThreadCount,
ContextType *context = nullptr);
static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
napi_env env,
const Object& resource,
ResourceString resourceName,
size_t maxQueueSize,
size_t initialThreadCount,
ContextType* context = nullptr);

// This API may only be called from the main thread.
// Creates a new threadsafe function with:
// Callback [missing] Resource [missing] Finalizer [passed]
template <typename ResourceString, typename Finalizer,
template <typename ResourceString,
typename Finalizer,
typename FinalizerDataType = void>
static TypedThreadSafeFunction<ContextType, DataType, CallJs>
New(napi_env env, ResourceString resourceName, size_t maxQueueSize,
size_t initialThreadCount, ContextType *context,
Finalizer finalizeCallback, FinalizerDataType *data = nullptr);
static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
napi_env env,
ResourceString resourceName,
size_t maxQueueSize,
size_t initialThreadCount,
ContextType* context,
Finalizer finalizeCallback,
FinalizerDataType* data = nullptr);

// This API may only be called from the main thread.
// Creates a new threadsafe function with:
// Callback [missing] Resource [passed] Finalizer [passed]
template <typename ResourceString, typename Finalizer,
template <typename ResourceString,
typename Finalizer,
typename FinalizerDataType = void>
static TypedThreadSafeFunction<ContextType, DataType, CallJs>
New(napi_env env, const Object &resource, ResourceString resourceName,
size_t maxQueueSize, size_t initialThreadCount, ContextType *context,
Finalizer finalizeCallback, FinalizerDataType *data = nullptr);
static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
napi_env env,
const Object& resource,
ResourceString resourceName,
size_t maxQueueSize,
size_t initialThreadCount,
ContextType* context,
Finalizer finalizeCallback,
FinalizerDataType* data = nullptr);
#endif

// This API may only be called from the main thread.
// Creates a new threadsafe function with:
// Callback [passed] Resource [missing] Finalizer [missing]
template <typename ResourceString>
static TypedThreadSafeFunction<ContextType, DataType, CallJs>
New(napi_env env, const Function &callback, ResourceString resourceName,
size_t maxQueueSize, size_t initialThreadCount,
ContextType *context = nullptr);
static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
napi_env env,
const Function& callback,
ResourceString resourceName,
size_t maxQueueSize,
size_t initialThreadCount,
ContextType* context = nullptr);

// This API may only be called from the main thread.
// Creates a new threadsafe function with:
// Callback [passed] Resource [passed] Finalizer [missing]
template <typename ResourceString>
static TypedThreadSafeFunction<ContextType, DataType, CallJs>
New(napi_env env, const Function &callback, const Object &resource,
ResourceString resourceName, size_t maxQueueSize,
size_t initialThreadCount, ContextType *context = nullptr);
static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
napi_env env,
const Function& callback,
const Object& resource,
ResourceString resourceName,
size_t maxQueueSize,
size_t initialThreadCount,
ContextType* context = nullptr);

// This API may only be called from the main thread.
// Creates a new threadsafe function with:
// Callback [passed] Resource [missing] Finalizer [passed]
template <typename ResourceString, typename Finalizer,
template <typename ResourceString,
typename Finalizer,
typename FinalizerDataType = void>
static TypedThreadSafeFunction<ContextType, DataType, CallJs>
New(napi_env env, const Function &callback, ResourceString resourceName,
size_t maxQueueSize, size_t initialThreadCount, ContextType *context,
Finalizer finalizeCallback, FinalizerDataType *data = nullptr);
static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
napi_env env,
const Function& callback,
ResourceString resourceName,
size_t maxQueueSize,
size_t initialThreadCount,
ContextType* context,
Finalizer finalizeCallback,
FinalizerDataType* data = nullptr);

// This API may only be called from the main thread.
// Creates a new threadsafe function with:
// Callback [passed] Resource [passed] Finalizer [passed]
template <typename CallbackType, typename ResourceString, typename Finalizer,
typename FinalizerDataType>
static TypedThreadSafeFunction<ContextType, DataType, CallJs>
New(napi_env env, CallbackType callback, const Object &resource,
ResourceString resourceName, size_t maxQueueSize,
size_t initialThreadCount, ContextType *context,
Finalizer finalizeCallback, FinalizerDataType *data = nullptr);
template <typename CallbackType,
typename ResourceString,
typename Finalizer,
typename FinalizerDataType>
static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
napi_env env,
CallbackType callback,
const Object& resource,
ResourceString resourceName,
size_t maxQueueSize,
size_t initialThreadCount,
ContextType* context,
Finalizer finalizeCallback,
FinalizerDataType* data = nullptr);

TypedThreadSafeFunction<ContextType, DataType, CallJs>();
TypedThreadSafeFunction<ContextType, DataType, CallJs>(
Expand All @@ -2355,10 +2392,10 @@ namespace Napi {
operator napi_threadsafe_function() const;

// This API may be called from any thread.
napi_status BlockingCall(DataType *data = nullptr) const;
napi_status BlockingCall(DataType* data = nullptr) const;

// This API may be called from any thread.
napi_status NonBlockingCall(DataType *data = nullptr) const;
napi_status NonBlockingCall(DataType* data = nullptr) const;

// This API may only be called from the main thread.
void Ref(napi_env env) const;
Expand All @@ -2376,22 +2413,30 @@ namespace Napi {
napi_status Abort();

// This API may be called from any thread.
ContextType *GetContext() const;
ContextType* GetContext() const;

private:
template <typename ResourceString, typename Finalizer,
private:
template <typename ResourceString,
typename Finalizer,
typename FinalizerDataType>
static TypedThreadSafeFunction<ContextType, DataType, CallJs>
New(napi_env env, const Function &callback, const Object &resource,
ResourceString resourceName, size_t maxQueueSize,
size_t initialThreadCount, ContextType *context,
Finalizer finalizeCallback, FinalizerDataType *data,
static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
napi_env env,
const Function& callback,
const Object& resource,
ResourceString resourceName,
size_t maxQueueSize,
size_t initialThreadCount,
ContextType* context,
Finalizer finalizeCallback,
FinalizerDataType* data,
napi_finalize wrapper);

static void CallJsInternal(napi_env env, napi_value jsCallback,
void *context, void *data);
static void CallJsInternal(napi_env env,
napi_value jsCallback,
void* context,
void* data);

protected:
protected:
napi_threadsafe_function _tsfn;
};
template <typename DataType>
Expand Down
15 changes: 10 additions & 5 deletions test/binding.cc
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,16 @@ Object Init(Env env, Object exports) {
exports.Set("threadsafe_function_sum", InitThreadSafeFunctionSum(env));
exports.Set("threadsafe_function_unref", InitThreadSafeFunctionUnref(env));
exports.Set("threadsafe_function", InitTypedThreadSafeFunction(env));
exports.Set("typed_threadsafe_function_ctx", InitTypedThreadSafeFunctionCtx(env));
exports.Set("typed_threadsafe_function_existing_tsfn", InitTypedThreadSafeFunctionExistingTsfn(env));
exports.Set("typed_threadsafe_function_ptr", InitTypedThreadSafeFunctionPtr(env));
exports.Set("typed_threadsafe_function_sum", InitTypedThreadSafeFunctionSum(env));
exports.Set("typed_threadsafe_function_unref", InitTypedThreadSafeFunctionUnref(env));
exports.Set("typed_threadsafe_function_ctx",
InitTypedThreadSafeFunctionCtx(env));
exports.Set("typed_threadsafe_function_existing_tsfn",
InitTypedThreadSafeFunctionExistingTsfn(env));
exports.Set("typed_threadsafe_function_ptr",
InitTypedThreadSafeFunctionPtr(env));
exports.Set("typed_threadsafe_function_sum",
InitTypedThreadSafeFunctionSum(env));
exports.Set("typed_threadsafe_function_unref",
InitTypedThreadSafeFunctionUnref(env));
exports.Set("typed_threadsafe_function", InitTypedThreadSafeFunction(env));
#endif
exports.Set("typedarray", InitTypedArray(env));
Expand Down
50 changes: 28 additions & 22 deletions test/typed_threadsafe_function/typed_threadsafe_function.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,17 @@ constexpr size_t MAX_QUEUE_SIZE = 2;
static std::thread threads[2];

static struct ThreadSafeFunctionInfo {
enum CallType {
DEFAULT,
BLOCKING,
NON_BLOCKING
} type;
enum CallType { DEFAULT, BLOCKING, NON_BLOCKING } type;
bool abort;
bool startSecondary;
FunctionReference jsFinalizeCallback;
uint32_t maxQueueSize;
} tsfnInfo;

static void TSFNCallJS(Env env, Function jsCallback,
ThreadSafeFunctionInfo * /* context */, int *data) {
static void TSFNCallJS(Env env,
Function jsCallback,
ThreadSafeFunctionInfo* /* context */,
int* data) {
// A null environment signifies the threadsafe function has been finalized.
if (!(env == nullptr || jsCallback == nullptr)) {
// If called with no data
Expand Down Expand Up @@ -82,24 +80,25 @@ static void DataSourceThread() {
// chance to abort.
auto start = std::chrono::high_resolution_clock::now();
constexpr auto MS_200 = std::chrono::milliseconds(200);
for (; std::chrono::high_resolution_clock::now() - start < MS_200;);
for (; std::chrono::high_resolution_clock::now() - start < MS_200;)
;
}

switch (status) {
case napi_queue_full:
queueWasFull = true;
index++;
// fall through
case napi_queue_full:
queueWasFull = true;
index++;
// fall through

case napi_ok:
continue;
case napi_ok:
continue;

case napi_closing:
queueWasClosing = true;
break;
case napi_closing:
queueWasClosing = true;
break;

default:
Error::Fatal("DataSourceThread", "ThreadSafeFunction.*Call() failed");
default:
Error::Fatal("DataSourceThread", "ThreadSafeFunction.*Call() failed");
}
}

Expand Down Expand Up @@ -141,14 +140,21 @@ static void JoinTheThreads(Env /* env */,
}

static Value StartThreadInternal(const CallbackInfo& info,
ThreadSafeFunctionInfo::CallType type) {
ThreadSafeFunctionInfo::CallType type) {
tsfnInfo.type = type;
tsfnInfo.abort = info[1].As<Boolean>();
tsfnInfo.startSecondary = info[2].As<Boolean>();
tsfnInfo.maxQueueSize = info[3].As<Number>().Uint32Value();

tsfn = TSFN::New(info.Env(), info[0].As<Function>(), Object::New(info.Env()),
"Test", tsfnInfo.maxQueueSize, 2, &tsfnInfo, JoinTheThreads, threads);
tsfn = TSFN::New(info.Env(),
info[0].As<Function>(),
Object::New(info.Env()),
"Test",
tsfnInfo.maxQueueSize,
2,
&tsfnInfo,
JoinTheThreads,
threads);

threads[0] = std::thread(DataSourceThread);

Expand Down
Loading

0 comments on commit 5e5b9ce

Please sign in to comment.