diff options
author | Dan Gudmundsson <[email protected]> | 2011-11-16 15:03:31 +0100 |
---|---|---|
committer | Dan Gudmundsson <[email protected]> | 2011-11-16 15:03:31 +0100 |
commit | f44805dc16feb213f65a65c9a74f1e3125976c2f (patch) | |
tree | 98b3ca5e51e534a1a0c95d2db819c68b4a794dad /lib/wx/c_src | |
parent | 88d995112219ca3339be12776757ef564cb04f8d (diff) | |
download | otp-f44805dc16feb213f65a65c9a74f1e3125976c2f.tar.gz otp-f44805dc16feb213f65a65c9a74f1e3125976c2f.tar.bz2 otp-f44805dc16feb213f65a65c9a74f1e3125976c2f.zip |
[wx] Fix deadlock in callback handling
New testcase showcase the deadlock
Diffstat (limited to 'lib/wx/c_src')
-rw-r--r-- | lib/wx/c_src/wxe_impl.cpp | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/lib/wx/c_src/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp index e430fbc7a2..69fcd4e362 100644 --- a/lib/wx/c_src/wxe_impl.cpp +++ b/lib/wx/c_src/wxe_impl.cpp @@ -331,9 +331,9 @@ void handle_event_callback(ErlDrvPort port, ErlDrvTermData process) driver_monitor_process(port, process, &monitor); // Should we be able to handle commands when recursing? probably erl_drv_mutex_lock(wxe_batch_locker_m); - // fprintf(stderr, "\r\nCB EV Start ");fflush(stderr); + //fprintf(stderr, "\r\nCB EV Start %lu \r\n", process);fflush(stderr); app->dispatch_cb(wxe_batch, wxe_batch_cb_saved, process); - // fprintf(stderr, ".. done \r\n");fflush(stderr); + //fprintf(stderr, "CB EV done %lu \r\n", process);fflush(stderr); wxe_batch_caller = 0; erl_drv_mutex_unlock(wxe_batch_locker_m); driver_demonitor_process(port, &monitor); @@ -430,8 +430,9 @@ void WxeApp::dispatch_cb(wxList * batch, wxList * temp, ErlDrvTermData process) wxeCommand *event = (wxeCommand *)node->GetData(); wxeMemEnv *memenv = getMemEnv(event->port); batch->Erase(node); + // fprintf(stderr, " Ev %d %lu\r\n", event->op, event->caller); if(event->caller == process || // Callbacks from CB process only - event->op == WXE_CB_START || // Recursive event callback allow + event->op == WXE_CB_START || // Event callback start change process // Allow connect_cb during CB i.e. msg from wxe_server. (memenv && event->caller == memenv->owner)) { @@ -453,6 +454,7 @@ void WxeApp::dispatch_cb(wxList * batch, wxList * temp, ErlDrvTermData process) break; default: erl_drv_mutex_unlock(wxe_batch_locker_m); + size_t start=temp->GetCount(); if(event->op < OPENGL_START) { // fprintf(stderr, " cb %d \r\n", event->op); wxe_dispatch(*event); @@ -460,9 +462,23 @@ void WxeApp::dispatch_cb(wxList * batch, wxList * temp, ErlDrvTermData process) gl_dispatch(event->op,event->buffer,event->caller,event->bin); } erl_drv_mutex_lock(wxe_batch_locker_m); - break; + if(temp->GetCount() > start) { + // We have recursed dispatch_cb and messages for this + // callback may be saved on temp list move them + // to orig list + for(wxList::compatibility_iterator node = temp->Item(start); + node; + node = node->GetNext()) { + wxeCommand *ev = (wxeCommand *)node->GetData(); + if(ev->caller == process) { + batch->Append(ev); + temp->Erase(node); + } + } + } if(callback_returned) return; + break; } delete event; } else { |