@@ -20,6 +20,7 @@ class CallbackBridge {
2020
2121 // Executes the callback
2222 T operator ()(std::vector<void *>);
23+ int timedout;
2324
2425 protected:
2526 // We will expose a bridge object to the JS callback that wraps this instance so we don't loose context.
@@ -60,7 +61,7 @@ template <typename T, typename L>
6061Nan::Persistent<v8::Function> CallbackBridge<T, L>::wrapper_constructor;
6162
6263template <typename T, typename L>
63- CallbackBridge<T, L>::CallbackBridge(v8::Local<v8::Function> callback, bool is_sync) : callback(new Nan::Callback(callback)), is_sync(is_sync) {
64+ CallbackBridge<T, L>::CallbackBridge(v8::Local<v8::Function> callback, bool is_sync) : timedout( 0 ), callback(new Nan::Callback(callback)), is_sync(is_sync) {
6465 /*
6566 * This is invoked from the main JavaScript thread.
6667 * V8 context is available.
@@ -70,7 +71,7 @@ CallbackBridge<T, L>::CallbackBridge(v8::Local<v8::Function> callback, bool is_s
7071}
7172
7273template <typename T, typename L>
73- CallbackBridge<T, L>::CallbackBridge(const CallbackBridge<T,L>& other) : callback(new Nan::Callback(other.callback->GetFunction ())), is_sync(other.is_sync) {
74+ CallbackBridge<T, L>::CallbackBridge(const CallbackBridge<T,L>& other) : timedout( 0 ), callback(new Nan::Callback(other.callback->GetFunction ())), is_sync(other.is_sync) {
7475 /*
7576 * This is invoked from the main JavaScript thread.
7677 * V8 context is available.
@@ -99,6 +100,7 @@ CallbackBridge<T, L>::operator= (const CallbackBridge<T,L>& other)
99100
100101 this ->callback = new Nan::Callback (other.callback ->GetFunction ());
101102 this ->is_sync = other.is_sync ;
103+ this ->timedout = 0 ;
102104 init_uv ();
103105 init_wrapper ();
104106 }
@@ -174,12 +176,12 @@ T CallbackBridge<T, L>::operator()(std::vector<void*> argv) {
174176 * async I/O executed from JavaScript callbacks.
175177 */
176178 this ->argv = argv;
177-
179+ this -> timedout = 0 ;
178180 uv_mutex_lock (&this ->cv_mutex );
179181 this ->has_returned = false ;
180182 uv_async_send (this ->async );
181- while (!this ->has_returned ) {
182- uv_cond_wait (&this ->condition_variable , &this ->cv_mutex );
183+ while (!this ->has_returned && this -> timedout == 0 ) {
184+ this -> timedout = uv_cond_timedwait (&this ->condition_variable , &this ->cv_mutex , 2 * ( uint64_t ) 1e9 );
183185 }
184186 uv_mutex_unlock (&this ->cv_mutex );
185187 return this ->return_value ;
@@ -199,16 +201,18 @@ void CallbackBridge<T, L>::dispatched_async_uv_callback(uv_async_t *req) {
199201 * from types invoked by pre_process_args() and
200202 * post_process_args().
201203 */
202- Nan::HandleScope scope;
203- Nan::TryCatch try_catch;
204+ if (!bridge->timedout ) {
205+ Nan::HandleScope scope;
206+ Nan::TryCatch try_catch;
204207
205- std::vector<v8::Local<v8::Value>> argv_v8 = bridge->pre_process_args (bridge->argv );
206- argv_v8.push_back (Nan::New (bridge->wrapper ));
208+ std::vector<v8::Local<v8::Value>> argv_v8 = bridge->pre_process_args (bridge->argv );
209+ argv_v8.push_back (Nan::New (bridge->wrapper ));
207210
208- bridge->callback ->Call (argv_v8.size (), &argv_v8[0 ]);
211+ bridge->callback ->Call (argv_v8.size (), &argv_v8[0 ]);
209212
210- if (try_catch.HasCaught ()) {
211- Nan::FatalException (try_catch);
213+ if (try_catch.HasCaught ()) {
214+ Nan::FatalException (try_catch);
215+ }
212216 }
213217}
214218
@@ -225,18 +229,20 @@ NAN_METHOD(CallbackBridge<T COMMA L>::ReturnCallback) {
225229 CallbackBridge<T, L>* bridge = static_cast <CallbackBridge<T, L>*>(Nan::GetInternalFieldPointer (info.This (), 0 ));
226230 Nan::TryCatch try_catch;
227231
228- bridge->return_value = bridge->post_process_return_value (info[0 ]);
232+ if (!bridge->timedout ) {
233+ bridge->return_value = bridge->post_process_return_value (info[0 ]);
229234
230- {
231- uv_mutex_lock (&bridge->cv_mutex );
232- bridge->has_returned = true ;
233- uv_mutex_unlock (&bridge->cv_mutex );
234- }
235+ {
236+ uv_mutex_lock (&bridge->cv_mutex );
237+ bridge->has_returned = true ;
238+ uv_mutex_unlock (&bridge->cv_mutex );
239+ }
235240
236- uv_cond_broadcast (&bridge->condition_variable );
241+ uv_cond_broadcast (&bridge->condition_variable );
237242
238- if (try_catch.HasCaught ()) {
239- Nan::FatalException (try_catch);
243+ if (try_catch.HasCaught ()) {
244+ Nan::FatalException (try_catch);
245+ }
240246 }
241247}
242248
0 commit comments