From 70cb9432dc03ac9435b2c8c5fe2e8fd0608015dc Mon Sep 17 00:00:00 2001 From: Dan Gudmundsson Date: Thu, 2 Jul 2015 19:22:37 +0200 Subject: wx: Event callbacks could hang wx application temporary After applying a command make sure that it didn't recurse to a callback invocation, then we must re-start from the saved command queue. --- lib/wx/c_src/wxe_impl.cpp | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'lib/wx/c_src/wxe_impl.cpp') diff --git a/lib/wx/c_src/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp index e6ed236962..5b34f08704 100644 --- a/lib/wx/c_src/wxe_impl.cpp +++ b/lib/wx/c_src/wxe_impl.cpp @@ -60,6 +60,7 @@ wxeFifo * wxe_queue = NULL; wxeFifo * wxe_queue_cb_saved = NULL; unsigned int wxe_needs_signal = 0; // inside batch if larger than 0 +unsigned int wxe_cb_invoked = 0; /* ************************************************************ * Commands from erlang @@ -233,6 +234,7 @@ void handle_event_callback(ErlDrvPort port, ErlDrvTermData process) app->recurse_level--; // fprintf(stderr, "CB EV done %lu \r\n", process);fflush(stderr); driver_demonitor_process(port, &monitor); + wxe_cb_invoked = 1; } } @@ -240,10 +242,16 @@ void WxeApp::dispatch_cmds() { if(wxe_status != WXE_INITIATED) return; - recurse_level++; - int level = dispatch(wxe_queue_cb_saved, 0, WXE_STORED); - dispatch(wxe_queue, level, WXE_NORMAL); - recurse_level--; + do { + wxe_cb_invoked = 0; + recurse_level++; + // fprintf(stderr, "\r\ndispatch_saved 0 \r\n");fflush(stderr); + int level = dispatch(wxe_queue_cb_saved, 0, WXE_STORED); + // fprintf(stderr, "\r\ndispatch_normal %d\r\n", level);fflush(stderr); + dispatch(wxe_queue, level, WXE_NORMAL); + // fprintf(stderr, "\r\ndispatch_done \r\n");fflush(stderr); + recurse_level--; + } while(wxe_cb_invoked); // Cleanup old memenv's and deleted objects if(recurse_level == 0) { @@ -313,7 +321,12 @@ int WxeApp::dispatch(wxeFifo * batch, int blevel, int list_type) break; } event->Delete(); - if(list_type == WXE_NORMAL) erl_drv_mutex_lock(wxe_batch_locker_m); + if(list_type == WXE_NORMAL) { + if(wxe_cb_invoked) + return blevel; + else + erl_drv_mutex_lock(wxe_batch_locker_m); + } } if(list_type == WXE_STORED) return blevel; -- cgit v1.2.3