From 7604209d02278b5547ae42fb328bfbc7d9043963 Mon Sep 17 00:00:00 2001 From: Dan Gudmundsson Date: Fri, 15 Apr 2016 10:19:59 +0200 Subject: wx: Fix callback problems Commands could be executed twice, if the command was dispatched from a callback and caused a recursive invocation of command loop. Solution is to mark op as -1 before calling wxWidgets. Also commands could be missed when idle processing was done inside while executing a recursive callback, solved be always resetting peak index after idle processing is done. --- lib/wx/c_src/gen/wxe_funcs.cpp | 14 ++++++++------ lib/wx/c_src/wxe_helpers.cpp | 4 ++-- lib/wx/c_src/wxe_helpers.h | 2 +- lib/wx/c_src/wxe_impl.cpp | 5 +++-- 4 files changed, 14 insertions(+), 11 deletions(-) (limited to 'lib/wx/c_src') diff --git a/lib/wx/c_src/gen/wxe_funcs.cpp b/lib/wx/c_src/gen/wxe_funcs.cpp index 059cee59f4..283e97f4e2 100644 --- a/lib/wx/c_src/gen/wxe_funcs.cpp +++ b/lib/wx/c_src/gen/wxe_funcs.cpp @@ -40,17 +40,19 @@ void WxeApp::wxe_dispatch(wxeCommand& Ecmd) { char * bp = Ecmd.buffer; + int op = Ecmd.op; + Ecmd.op = -1; wxeMemEnv *memenv = getMemEnv(Ecmd.port); - wxeReturn rt = wxeReturn(WXE_DRV_PORT, Ecmd.caller, true); + wxeReturn rt = wxeReturn(WXE_DRV_PORT, Ecmd.caller, true); try { - switch (Ecmd.op) + switch (op) { case DESTROY_OBJECT: { void *This = getPtr(bp,memenv); wxeRefData *refd = getRefData(This); if(This && refd) { if(recurse_level > 1 && refd->type != 4) { - delayed_delete->Append(Ecmd.Save()); + delayed_delete->Append(Ecmd.Save(op)); } else { delete_object(This, refd); ((WxeApp *) wxTheApp)->clearPtr(This);} @@ -114,7 +116,7 @@ case 101: { // wxEvtHandler::Disconnect int eventType = wxeEventTypeFromAtom(bp); bp += *eventTypeLen; if(eventType > 0) { if(recurse_level > 1) { - delayed_delete->Append(Ecmd.Save()); + delayed_delete->Append(Ecmd.Save(op)); } else { bool Result = This->Disconnect((int) *winid,(int) *lastId,eventType, (wxObjectEventFunction)(wxEventFunction) @@ -32077,7 +32079,7 @@ case wxDCOverlay_Clear: { // wxDCOverlay::Clear } default: { wxeReturn error = wxeReturn(WXE_DRV_PORT, Ecmd.caller, false); error.addAtom("_wxe_error_"); - error.addInt((int) Ecmd.op); + error.addInt((int) op); error.addAtom("not_supported"); error.addTupleCount(3); error.send(); @@ -32087,7 +32089,7 @@ case wxDCOverlay_Clear: { // wxDCOverlay::Clear rt.send(); } catch (wxe_badarg badarg) { // try wxeReturn error = wxeReturn(WXE_DRV_PORT, Ecmd.caller, false); error.addAtom("_wxe_error_"); - error.addInt((int) Ecmd.op); + error.addInt((int) op); error.addAtom("badarg"); error.addInt((int) badarg.ref); error.addTupleCount(2); diff --git a/lib/wx/c_src/wxe_helpers.cpp b/lib/wx/c_src/wxe_helpers.cpp index 76958a346f..4798e605e8 100644 --- a/lib/wx/c_src/wxe_helpers.cpp +++ b/lib/wx/c_src/wxe_helpers.cpp @@ -47,8 +47,8 @@ void wxeCommand::Delete() if(len > 64) driver_free(buffer); buffer = NULL; - op = -1; } + op = -1; } /* **************************************************************************** @@ -226,7 +226,7 @@ unsigned int wxeFifo::Cleanup(unsigned int def) // Realloced we need to start from the beginning return 0; } else { - return def; + return def < cb_start? def : cb_start; } } diff --git a/lib/wx/c_src/wxe_helpers.h b/lib/wx/c_src/wxe_helpers.h index 3f66b6d97a..70ffccdc13 100644 --- a/lib/wx/c_src/wxe_helpers.h +++ b/lib/wx/c_src/wxe_helpers.h @@ -46,7 +46,7 @@ class wxeCommand wxeCommand(); virtual ~wxeCommand(); // Use Delete() - wxeCommand * Save() { return this; }; + wxeCommand * Save(int Op) { op = Op; return this; }; void Delete(); ErlDrvTermData caller; diff --git a/lib/wx/c_src/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp index f899839782..175bcfce54 100644 --- a/lib/wx/c_src/wxe_impl.cpp +++ b/lib/wx/c_src/wxe_impl.cpp @@ -238,9 +238,10 @@ void WxeApp::dispatch_cmds() if(wxe_status != WXE_INITIATED) return; recurse_level++; - // fprintf(stderr, "\r\ndispatch_normal %d\r\n", level);fflush(stderr); + // fprintf(stderr, "\r\ndispatch_normal %d\r\n", recurse_level);fflush(stderr); + wxe_queue->cb_start = 0; dispatch(wxe_queue); - // fprintf(stderr, "\r\ndispatch_done \r\n");fflush(stderr); + // fprintf(stderr, "\r\ndispatch_done %d\r\n", recurse_level);fflush(stderr); recurse_level--; // Cleanup old memenv's and deleted objects -- cgit v1.2.3