@@ -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 }
@@ -179,12 +181,12 @@ T CallbackBridge<T, L>::operator()(std::vector<void*> argv) {
179181 * async I/O executed from JavaScript callbacks.
180182 */
181183 this ->argv = argv;
182-
184+ this -> timedout = 0 ;
183185 uv_mutex_lock (&this ->cv_mutex );
184186 this ->has_returned = false ;
185187 uv_async_send (this ->async );
186- while (!this ->has_returned ) {
187- uv_cond_wait (&this ->condition_variable , &this ->cv_mutex );
188+ while (!this ->has_returned && this -> timedout == 0 ) {
189+ this -> timedout = uv_cond_timedwait (&this ->condition_variable , &this ->cv_mutex , 2 * ( uint64_t ) 1e9 );
188190 }
189191 uv_mutex_unlock (&this ->cv_mutex );
190192 return this ->return_value ;
@@ -204,19 +206,21 @@ void CallbackBridge<T, L>::dispatched_async_uv_callback(uv_async_t *req) {
204206 * from types invoked by pre_process_args() and
205207 * post_process_args().
206208 */
207- Nan::HandleScope scope;
208- Nan::TryCatch try_catch;
209+ if (!bridge->timedout ) {
210+ Nan::HandleScope scope;
211+ Nan::TryCatch try_catch;
209212
210- std::vector<v8::Local<v8::Value>> argv_v8 = bridge->pre_process_args (bridge->argv );
211- if (try_catch.HasCaught ()) {
212- Nan::FatalException (try_catch);
213- }
214- argv_v8.push_back (Nan::New (bridge->wrapper ));
213+ std::vector<v8::Local<v8::Value>> argv_v8 = bridge->pre_process_args (bridge->argv );
214+ if (try_catch.HasCaught ()) {
215+ Nan::FatalException (try_catch);
216+ }
217+ argv_v8.push_back (Nan::New (bridge->wrapper ));
215218
216- bridge->callback ->Call (argv_v8.size (), &argv_v8[0 ]);
219+ bridge->callback ->Call (argv_v8.size (), &argv_v8[0 ]);
217220
218- if (try_catch.HasCaught ()) {
219- Nan::FatalException (try_catch);
221+ if (try_catch.HasCaught ()) {
222+ Nan::FatalException (try_catch);
223+ }
220224 }
221225}
222226
@@ -233,18 +237,20 @@ NAN_METHOD(CallbackBridge<T COMMA L>::ReturnCallback) {
233237 CallbackBridge<T, L>* bridge = static_cast <CallbackBridge<T, L>*>(Nan::GetInternalFieldPointer (info.This (), 0 ));
234238 Nan::TryCatch try_catch;
235239
236- bridge->return_value = bridge->post_process_return_value (info[0 ]);
240+ if (!bridge->timedout ) {
241+ bridge->return_value = bridge->post_process_return_value (info[0 ]);
237242
238- {
239- uv_mutex_lock (&bridge->cv_mutex );
240- bridge->has_returned = true ;
241- uv_mutex_unlock (&bridge->cv_mutex );
242- }
243+ {
244+ uv_mutex_lock (&bridge->cv_mutex );
245+ bridge->has_returned = true ;
246+ uv_mutex_unlock (&bridge->cv_mutex );
247+ }
243248
244- uv_cond_broadcast (&bridge->condition_variable );
249+ uv_cond_broadcast (&bridge->condition_variable );
245250
246- if (try_catch.HasCaught ()) {
247- Nan::FatalException (try_catch);
251+ if (try_catch.HasCaught ()) {
252+ Nan::FatalException (try_catch);
253+ }
248254 }
249255}
250256
0 commit comments