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 issues with next tick never running #549

Merged
merged 2 commits into from
May 7, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions binding.gyp
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
##
# Portions Copyright (c) Microsoft Corporation. All rights reserved.
#
# Portions Copyright (c) Microsoft Corporation. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# http://www.apache.org/licenses/LICENSE-2.0
#
# THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
# OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
# ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR
# PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
# OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
# ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR
# PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
#
# See the Apache Version 2.0 License for specific language governing
# See the Apache Version 2.0 License for specific language governing
# permissions and limitations under the License.
##
{
Expand Down Expand Up @@ -59,6 +59,7 @@
},
'sources+': [
'src/common/v8synchronizationcontext.cpp',
'src/common/callbackhelper.cpp',
'src/common/edge.cpp',
'src/CoreCLREmbedding/coreclrembedding.cpp',
'src/CoreCLREmbedding/coreclrfunc.cpp',
Expand Down Expand Up @@ -181,6 +182,7 @@
'src/dotnet/clrfuncreflectionwrap.cpp',
'src/dotnet/clractioncontext.cpp',
'src/common/v8synchronizationcontext.cpp',
'src/common/callbackhelper.cpp',
'src/common/edge.cpp'
]
},
Expand All @@ -201,6 +203,7 @@
'src/mono/utils.cpp',
'src/common/utils.cpp',
'src/common/v8synchronizationcontext.cpp',
'src/common/callbackhelper.cpp',
'src/common/edge.cpp'
],
'include_dirs': [
Expand Down Expand Up @@ -330,7 +333,7 @@
],
'outputs': [
'lib/bootstrap/bin/$(BUILDTYPE)/netstandard1.6/bootstrap.dll'
],
],
'action': [
'bash',
'-c',
Expand Down
Binary file modified lib/native/win32/ia32/0.12.0/edge_coreclr.node
Binary file not shown.
Binary file modified lib/native/win32/ia32/0.12.0/edge_nativeclr.node
Binary file not shown.
Binary file modified lib/native/win32/ia32/0.8.22/edge_coreclr.node
Binary file not shown.
Binary file modified lib/native/win32/ia32/0.8.22/edge_nativeclr.node
Binary file not shown.
Binary file modified lib/native/win32/ia32/4.1.1/edge_coreclr.node
Binary file not shown.
Binary file modified lib/native/win32/ia32/4.1.1/edge_nativeclr.node
Binary file not shown.
Binary file modified lib/native/win32/ia32/5.1.0/edge_coreclr.node
Binary file not shown.
Binary file modified lib/native/win32/ia32/5.1.0/edge_nativeclr.node
Binary file not shown.
Binary file modified lib/native/win32/ia32/6.4.0/edge_coreclr.node
Binary file not shown.
Binary file modified lib/native/win32/ia32/6.4.0/edge_nativeclr.node
Binary file not shown.
Binary file modified lib/native/win32/x64/0.12.0/edge_coreclr.node
Binary file not shown.
Binary file modified lib/native/win32/x64/0.12.0/edge_nativeclr.node
Binary file not shown.
Binary file modified lib/native/win32/x64/0.8.22/edge_coreclr.node
Binary file not shown.
Binary file modified lib/native/win32/x64/0.8.22/edge_nativeclr.node
Binary file not shown.
Binary file modified lib/native/win32/x64/4.1.1/edge_coreclr.node
Binary file not shown.
Binary file modified lib/native/win32/x64/4.1.1/edge_nativeclr.node
Binary file not shown.
Binary file modified lib/native/win32/x64/5.1.0/edge_coreclr.node
Binary file not shown.
Binary file modified lib/native/win32/x64/5.1.0/edge_nativeclr.node
Binary file not shown.
Binary file modified lib/native/win32/x64/6.4.0/edge_coreclr.node
Binary file not shown.
Binary file modified lib/native/win32/x64/6.4.0/edge_nativeclr.node
Binary file not shown.
24 changes: 24 additions & 0 deletions src/common/callbackhelper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include "edge_common.h"

// The Callback to use to force the next tick to happen
Nan::Callback* CallbackHelper::tickCallback;

static void NoOpFunction(const Nan::FunctionCallbackInfo<v8::Value>& info)
{
// Do nothing, this is a no-op function
}

// Initialize the callback
void CallbackHelper::Initialize()
{
DBG("CallbackHelper::Initialize");

tickCallback = new Nan::Callback(Nan::New<v8::Function>(NoOpFunction, Nan::Null()));
}

// Make the no-op callback, forcing the next tick to execute
void CallbackHelper::KickNextTick()
{
Nan::HandleScope scope;
tickCallback->Call(0, 0);
}
1 change: 1 addition & 0 deletions src/common/edge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ NAN_MODULE_INIT(init)
DBG("edge::init");

V8SynchronizationContext::Initialize();
CallbackHelper::Initialize();

#ifdef HAVE_CORECLR
if (FAILED(CoreClrEmbedding::Initialize(debugMode)))
Expand Down
15 changes: 12 additions & 3 deletions src/common/edge_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,14 @@ class V8SynchronizationContext {

public:

// The node process will not exit until ExecuteAction or CancelAction had been called for all actions
// registered by calling RegisterAction on V8 thread. Actions registered by calling RegisterAction
// The node process will not exit until ExecuteAction or CancelAction had been called for all actions
// registered by calling RegisterAction on V8 thread. Actions registered by calling RegisterAction
// on CLR thread do not prevent the process from exiting.
// Calls from JavaScript to .NET always call RegisterAction on V8 thread before invoking .NET code.
// Calls from .NET to JavaScript call RegisterAction either on CLR or V8 thread, depending on
// whether .NET code executes synchronously on V8 thread it strarted running on.
// This means that if any call of a .NET function from JavaScript is in progress, the process won't exit.
// It also means that existence of .NET proxies to JavaScript functions in the CLR does not prevent the
// It also means that existence of .NET proxies to JavaScript functions in the CLR does not prevent the
// process from exiting.
// In this model, JavaScript owns the lifetime of the process.

Expand All @@ -102,6 +102,15 @@ class V8SynchronizationContext {
static void Unref(uv_edge_async_t* uv_edge_async);
};

class CallbackHelper {
private:
static Nan::Callback* tickCallback;

public:
static void Initialize();
static void KickNextTick();
};

typedef enum taskStatus
{
TaskStatusCreated = 0,
Expand Down
26 changes: 13 additions & 13 deletions src/common/v8synchronizationcontext.cpp
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
/**
* Portions Copyright (c) Microsoft Corporation. All rights reserved.
*
* Portions Copyright (c) Microsoft Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
* OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
* ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR
* PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
* OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
* ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR
* PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
*
* See the Apache Version 2.0 License for specific language governing
* See the Apache Version 2.0 License for specific language governing
* permissions and limitations under the License.
*/
#include "edge_common.h"
Expand All @@ -33,7 +33,7 @@ unsigned long V8SynchronizationContext::v8ThreadId;
uv_sem_t* V8SynchronizationContext::funcWaitHandle;
uv_edge_async_t* V8SynchronizationContext::uv_edge_async;

void V8SynchronizationContext::Initialize()
void V8SynchronizationContext::Initialize()
{
// This executes on V8 thread

Expand Down Expand Up @@ -61,19 +61,19 @@ uv_edge_async_t* V8SynchronizationContext::RegisterAction(uv_async_edge_cb actio
{
// This executes on V8 thread.
// Allocate new uv_edge_async.

DBG("V8SynchronizationContext::RegisterAction on v8 thread");
uv_edge_async_t* uv_edge_async = new uv_edge_async_t;
uv_edge_async->action = action;
uv_edge_async->data = data;
uv_edge_async->singleton = FALSE;
uv_async_init(uv_default_loop(), &uv_edge_async->uv_async, (uv_async_cb)continueOnV8Thread);
return uv_edge_async;
}
else
else
{
// This executes on CLR thread.
// This executes on CLR thread.
// Acquire exlusive access to uv_edge_async previously initialized on V8 thread.

DBG("V8SynchronizationContext::RegisterAction on CLR thread");
uv_sem_wait(V8SynchronizationContext::funcWaitHandle);
V8SynchronizationContext::uv_edge_async->action = action;
V8SynchronizationContext::uv_edge_async->data = data;
Expand All @@ -84,7 +84,7 @@ uv_edge_async_t* V8SynchronizationContext::RegisterAction(uv_async_edge_cb actio
void V8SynchronizationContext::ExecuteAction(uv_edge_async_t* uv_edge_async)
{
DBG("V8SynchronizationContext::ExecuteAction");
// Transfer control to completeOnV8hread method executing on V8 thread
// Transfer control to continueOnV8Thread method executing on V8 thread
uv_async_send(&uv_edge_async->uv_async);
}

Expand Down
2 changes: 1 addition & 1 deletion src/dotnet/clrfunc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ v8::Local<v8::Function> ClrFunc::Initialize(System::Func<System::Object^,Task<Sy

v8::Local<v8::Value> factoryArgv[] = { Nan::New(proxyFunction), Nan::New<v8::External>((void*)wrap) };
v8::Local<v8::Function> funcProxy =
(Nan::New(proxyFactory)->Call(Nan::GetCurrentContext()->Global(), 2, factoryArgv)).As<v8::Function>();
(Nan::Call(Nan::New(proxyFactory), Nan::GetCurrentContext()->Global(), 2, factoryArgv)).ToLocalChecked().As<v8::Function>();
Nan::Persistent<v8::Function> funcProxyPersistent(funcProxy);
funcProxyPersistent.SetWeak((void*)wrap, &clrFuncProxyNearDeath, Nan::WeakCallbackType::kParameter);

Expand Down
34 changes: 17 additions & 17 deletions src/dotnet/clrfuncinvokecontext.cpp
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
/**
* Portions Copyright (c) Microsoft Corporation. All rights reserved.
*
* Portions Copyright (c) Microsoft Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
* OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
* ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR
* PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
* OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
* ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR
* PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
*
* See the Apache Version 2.0 License for specific language governing
* See the Apache Version 2.0 License for specific language governing
* permissions and limitations under the License.
*/
#include "edge.h"
Expand All @@ -21,12 +21,10 @@ ClrFuncInvokeContext::ClrFuncInvokeContext(v8::Local<v8::Value> callbackOrSync)
DBG("ClrFuncInvokeContext::ClrFuncInvokeContext");
if (callbackOrSync->IsFunction())
{
this->callback = new Nan::Persistent<v8::Function>;
v8::Local<v8::Function> callbackOrSyncFunction = v8::Local<v8::Function>::Cast(callbackOrSync);
(this->callback)->Reset(callbackOrSyncFunction);
this->callback = new Nan::Callback(v8::Local<v8::Function>::Cast(callbackOrSync));
this->Sync = false;
}
else
else
{
this->Sync = callbackOrSync->BooleanValue();
}
Expand All @@ -41,7 +39,7 @@ void ClrFuncInvokeContext::DisposeCallback()
DBG("ClrFuncInvokeContext::DisposeCallback");
this->callback->Reset();
delete this->callback;
this->callback = NULL;
this->callback = NULL;
}
}

Expand All @@ -54,7 +52,7 @@ void ClrFuncInvokeContext::CompleteOnCLRThread(System::Threading::Tasks::Task<Sy

void ClrFuncInvokeContext::InitializeAsyncOperation()
{
// Create a uv_edge_async instance representing V8 async operation that will complete
// Create a uv_edge_async instance representing V8 async operation that will complete
// when the CLR function completes. The ClrActionContext is used to ensure the ClrFuncInvokeContext
// remains GC-rooted while the CLR function executes.

Expand Down Expand Up @@ -119,17 +117,19 @@ v8::Local<v8::Value> ClrFuncInvokeContext::CompleteOnV8Thread()
{
// complete the asynchronous call to C# by invoking a callback in JavaScript
Nan::TryCatch try_catch;
Nan::New<v8::Function>(*(this->callback))->Call(Nan::GetCurrentContext()->Global(), argc, argv);
DBG("ClrFuncInvokeContext::CompleteOnV8Thread - calling JS callback");
this->callback->Call(argc, argv);
this->DisposeCallback();
if (try_catch.HasCaught())
if (try_catch.HasCaught())
{
DBG("ClrFuncInvokeContext::CompleteOnV8Thread - exception in callback");
Nan::FatalException(try_catch);
}
}

DBG("ClrFuncInvokeContext::CompleteOnV8Thread - async with callback");
return scope.Escape(Nan::Undefined());
}
else if (1 == argc)
else if (1 == argc)
{
DBG("ClrFuncInvokeContext::CompleteOnV8Thread - handleScope.Close(ThrowException(argv[0]))");
// complete the synchronous call to C# by re-throwing the resulting exception
Expand Down
20 changes: 10 additions & 10 deletions src/dotnet/edge.h
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
/**
* Portions Copyright (c) Microsoft Corporation. All rights reserved.
*
* Portions Copyright (c) Microsoft Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
* OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
* ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR
* PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
* OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
* ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR
* PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
*
* See the Apache Version 2.0 License for specific language governing
* See the Apache Version 2.0 License for specific language governing
* permissions and limitations under the License.
*/
#ifndef __EDGE_H
Expand Down Expand Up @@ -42,7 +42,7 @@ typedef struct clrActionContext {

ref class ClrFuncInvokeContext {
private:
Nan::Persistent<v8::Function>* callback;
Nan::Callback* callback;
uv_edge_async_t* uv_edge_async;

void DisposeCallback();
Expand Down Expand Up @@ -114,7 +114,7 @@ ref class NodejsFuncInvokeContext {
ref class ClrFuncReflectionWrap {
private:
System::Object^ instance;
MethodInfo^ invokeMethod;
MethodInfo^ invokeMethod;

ClrFuncReflectionWrap();

Expand All @@ -138,7 +138,7 @@ ref class ClrFunc {
v8::Local<v8::Value> Call(v8::Local<v8::Value> payload, v8::Local<v8::Value> callback);
static v8::Local<v8::Value> MarshalCLRToV8(System::Object^ netdata);
static v8::Local<v8::Value> MarshalCLRExceptionToV8(System::Exception^ exception);
static System::Object^ MarshalV8ToCLR(v8::Local<v8::Value> jsdata);
static System::Object^ MarshalV8ToCLR(v8::Local<v8::Value> jsdata);
};

typedef struct clrFuncWrap {
Expand Down
Loading