Commit fce09934 by Michael Mifsud

Merge pull request #854 from saper/fix/713

Close #713 (handle->flags & UV_CLOSING) assertion failure
parents 028624c0 ec4eb0c6
...@@ -23,6 +23,7 @@ class CallbackBridge { ...@@ -23,6 +23,7 @@ class CallbackBridge {
// We will expose a bridge object to the JS callback that wraps this instance so we don't loose context. // We will expose a bridge object to the JS callback that wraps this instance so we don't loose context.
// This is the V8 constructor for such objects. // This is the V8 constructor for such objects.
static Handle<Function> get_wrapper_constructor(); static Handle<Function> get_wrapper_constructor();
static void async_gone(uv_handle_t *handle);
static NAN_METHOD(New); static NAN_METHOD(New);
static NAN_METHOD(ReturnCallback); static NAN_METHOD(ReturnCallback);
static Persistent<Function> wrapper_constructor; static Persistent<Function> wrapper_constructor;
...@@ -45,7 +46,7 @@ class CallbackBridge { ...@@ -45,7 +46,7 @@ class CallbackBridge {
std::mutex cv_mutex; std::mutex cv_mutex;
std::condition_variable condition_variable; std::condition_variable condition_variable;
uv_async_t async; uv_async_t *async;
std::vector<L> argv; std::vector<L> argv;
bool has_returned; bool has_returned;
T return_value; T return_value;
...@@ -58,8 +59,9 @@ template <typename T, typename L> ...@@ -58,8 +59,9 @@ template <typename T, typename L>
CallbackBridge<T, L>::CallbackBridge(NanCallback* callback, bool is_sync) : callback(callback), is_sync(is_sync) { CallbackBridge<T, L>::CallbackBridge(NanCallback* callback, bool is_sync) : callback(callback), is_sync(is_sync) {
// This assumes the main thread will be the one instantiating the bridge // This assumes the main thread will be the one instantiating the bridge
if (!is_sync) { if (!is_sync) {
uv_async_init(uv_default_loop(), &this->async, (uv_async_cb) dispatched_async_uv_callback); this->async = new uv_async_t;
this->async.data = (void*) this; this->async->data = (void*) this;
uv_async_init(uv_default_loop(), this->async, (uv_async_cb) dispatched_async_uv_callback);
} }
NanAssignPersistent(wrapper, NanNew(CallbackBridge<T, L>::get_wrapper_constructor())->NewInstance()); NanAssignPersistent(wrapper, NanNew(CallbackBridge<T, L>::get_wrapper_constructor())->NewInstance());
...@@ -72,7 +74,7 @@ CallbackBridge<T, L>::~CallbackBridge() { ...@@ -72,7 +74,7 @@ CallbackBridge<T, L>::~CallbackBridge() {
NanDisposePersistent(this->wrapper); NanDisposePersistent(this->wrapper);
if (!is_sync) { if (!is_sync) {
uv_close((uv_handle_t*)&this->async, NULL); uv_close((uv_handle_t*)this->async, &async_gone);
} }
} }
...@@ -93,7 +95,7 @@ T CallbackBridge<T, L>::operator()(std::vector<void*> argv) { ...@@ -93,7 +95,7 @@ T CallbackBridge<T, L>::operator()(std::vector<void*> argv) {
std::unique_lock<std::mutex> lock(this->cv_mutex); std::unique_lock<std::mutex> lock(this->cv_mutex);
this->has_returned = false; this->has_returned = false;
uv_async_send(&this->async); uv_async_send(this->async);
this->condition_variable.wait(lock, [this] { return this->has_returned; }); this->condition_variable.wait(lock, [this] { return this->has_returned; });
return this->return_value; return this->return_value;
...@@ -162,4 +164,9 @@ NAN_METHOD(CallbackBridge<T COMMA L>::New) { ...@@ -162,4 +164,9 @@ NAN_METHOD(CallbackBridge<T COMMA L>::New) {
NanReturnValue(args.This()); NanReturnValue(args.This());
} }
template <typename T, typename L>
void CallbackBridge<T, L>::async_gone(uv_handle_t *handle) {
delete (uv_async_t *)handle;
}
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment