From 58bf309625bb2fc99a7689d3ce2dcb6de2a3a04c Mon Sep 17 00:00:00 2001 From: Patrik Nyblom Date: Fri, 26 Feb 2010 16:23:27 +0100 Subject: wx: Correct usage of driver callbacks from wx thread --- lib/wx/c_src/wxe_driver.c | 3 ++- lib/wx/c_src/wxe_driver.h | 1 + lib/wx/c_src/wxe_impl.cpp | 16 +++++++++++++--- lib/wx/c_src/wxe_impl.h | 5 +++-- 4 files changed, 19 insertions(+), 6 deletions(-) (limited to 'lib/wx') diff --git a/lib/wx/c_src/wxe_driver.c b/lib/wx/c_src/wxe_driver.c index 3b951bec57..c927deb0ef 100644 --- a/lib/wx/c_src/wxe_driver.c +++ b/lib/wx/c_src/wxe_driver.c @@ -113,6 +113,7 @@ wxe_driver_start(ErlDrvPort port, char *buff) data->driver_data = NULL; data->bin = NULL; data->port = port; + data->pdl = driver_pdl_create(port); if(WXE_DRV_PORT == 0) { for(; *buff != 32; buff++); buff++; @@ -124,7 +125,7 @@ wxe_driver_start(ErlDrvPort port, char *buff) if(!(start_native_gui(data) == 1)) return(ERL_DRV_ERROR_GENERAL); /* ENOMEM */ } else { - meta_command(CREATE_PORT,data); + meta_command(CREATE_PORT,data); } return (ErlDrvData) data; } diff --git a/lib/wx/c_src/wxe_driver.h b/lib/wx/c_src/wxe_driver.h index 8437b4eb36..47a2a86e31 100644 --- a/lib/wx/c_src/wxe_driver.h +++ b/lib/wx/c_src/wxe_driver.h @@ -45,6 +45,7 @@ typedef struct wxe_data_def { WXEBinRef * bin; /* Argument binaries */ ErlDrvPort port; int is_cbport; + ErlDrvPDL pdl; } wxe_data; diff --git a/lib/wx/c_src/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp index 4486dff63b..528a08e654 100644 --- a/lib/wx/c_src/wxe_impl.cpp +++ b/lib/wx/c_src/wxe_impl.cpp @@ -101,7 +101,7 @@ int start_native_gui(wxe_data *sd) init_caller = driver_connected(sd->port); if((res = erl_drv_thread_create((char *)"wxwidgets", - &wxe_thread,wxe_main_loop,NULL,NULL)) == 0) { + &wxe_thread,wxe_main_loop,(void *) sd->pdl,NULL)) == 0) { erl_drv_mutex_lock(wxe_status_m); for(;wxe_status == WXE_NOT_INITIATED;) { erl_drv_cond_wait(wxe_status_c, wxe_status_m); @@ -179,12 +179,15 @@ void meta_command(int what, wxe_data *sd) { * wxWidgets Thread * ************************************************************/ -void *wxe_main_loop(void * not_used) +void *wxe_main_loop(void *vpdl) { int result; int argc = 1; char * temp = (char *) "Erlang\0"; char ** argv = &temp; + ErlDrvPDL pdl = (ErlDrvPDL) vpdl; + + driver_pdl_inc_refc(pdl); // ErlDrvSysInfo einfo; // driver_system_info(&einfo, sizeof(ErlDrvSysInfo)); @@ -199,6 +202,7 @@ void *wxe_main_loop(void * not_used) if(result >= 0 && wxe_status == WXE_INITIATED) { /* We are done try to make a clean exit */ wxe_status = WXE_EXITED; + driver_pdl_dec_refc(pdl); erl_drv_thread_exit(NULL); return NULL; } else { @@ -206,6 +210,7 @@ void *wxe_main_loop(void * not_used) wxe_status = WXE_ERROR; erl_drv_cond_signal(wxe_status_c); erl_drv_mutex_unlock(wxe_status_m); + driver_pdl_dec_refc(pdl); return NULL; } } @@ -401,11 +406,12 @@ void WxeApp::dispatch_cb(wxList * batch, wxList * temp, ErlDrvTermData process) node = batch->GetFirst()) { wxeCommand *event = (wxeCommand *)node->GetData(); + wxeMemEnv *memenv = getMemEnv(event->port); batch->Erase(node); if(event->caller == process || // Callbacks from CB process only event->op == WXE_CB_START || // Recursive event callback allow // Allow connect_cb during CB i.e. msg from wxe_server. - event->caller == driver_connected(event->port)) + event->caller == memenv->owner) { switch(event->op) { case WXE_BATCH_END: @@ -456,6 +462,9 @@ void WxeApp::dispatch_cb(wxList * batch, wxList * temp, ErlDrvTermData process) void WxeApp::newMemEnv(wxeMetaCommand& Ecmd) { wxeMemEnv * memenv = new wxeMemEnv(); + + driver_pdl_inc_refc(Ecmd.pdl); + for(int i = 0; i < global_me->next; i++) { memenv->ref2ptr[i] = global_me->ref2ptr[i]; } @@ -576,6 +585,7 @@ void WxeApp::destroyMemEnv(wxeMetaCommand& Ecmd) { // } // fflush(stderr); delete memenv; + driver_pdl_dec_refc(Ecmd.pdl); refmap.erase((ErlDrvTermData) Ecmd.port); } diff --git a/lib/wx/c_src/wxe_impl.h b/lib/wx/c_src/wxe_impl.h index 5e9d596633..e6d5169cbc 100644 --- a/lib/wx/c_src/wxe_impl.h +++ b/lib/wx/c_src/wxe_impl.h @@ -34,15 +34,16 @@ class wxeMetaCommand : public wxEvent public: wxeMetaCommand(wxe_data *sd, int EvId) : wxEvent(EvId, wxeEVT_META_COMMAND) - { caller = driver_caller(sd->port); port = sd->port; } ; + { caller = driver_caller(sd->port); port = sd->port; pdl = sd->pdl; } ; wxeMetaCommand(const wxeMetaCommand& event) : wxEvent(event) - { caller = event.caller; port = event.port; }; + { caller = event.caller; port = event.port; pdl = event.pdl; }; virtual ~wxeMetaCommand() {}; virtual wxEvent *Clone() const { return new wxeMetaCommand(*this); } ErlDrvTermData caller; ErlDrvPort port; + ErlDrvPDL pdl; }; class wxeCommand : public wxObject -- cgit v1.2.3