diff options
Diffstat (limited to 'lib/wx/c_src/wxe_impl.cpp')
-rw-r--r-- | lib/wx/c_src/wxe_impl.cpp | 58 |
1 files changed, 48 insertions, 10 deletions
diff --git a/lib/wx/c_src/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp index 4486dff63b..365fb691a1 100644 --- a/lib/wx/c_src/wxe_impl.cpp +++ b/lib/wx/c_src/wxe_impl.cpp @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2008-2010. All Rights Reserved. + * Copyright Ericsson AB 2008-2011. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -68,7 +68,6 @@ ErlDrvTermData wxe_batch_caller = 0; ErlDrvTermData init_caller = 0; // extern opengl -extern int gl_initiated; void gl_dispatch(int op, char *bp, ErlDrvTermData caller, WXEBinRef *bins[]); @@ -79,6 +78,21 @@ extern void erts_thread_disable_fpe(void); } #endif +#if defined(__APPLE__) && defined(__MACH__) && !defined(__DARWIN__) +#define __DARWIN__ 1 +#endif + +#ifdef __DARWIN__ +extern "C" { + int erl_drv_stolen_main_thread_join(ErlDrvTid tid, void **respp); + int erl_drv_steal_main_thread(char *name, + ErlDrvTid *dtid, + void* (*func)(void*), + void* arg, + ErlDrvThreadOpts *opts); +} +#endif + void *wxe_main_loop(void * ); /* ************************************************************ @@ -100,8 +114,14 @@ int start_native_gui(wxe_data *sd) wxe_batch_locker_c = erl_drv_cond_create((char *)"wxe_batch_locker_c"); init_caller = driver_connected(sd->port); - if((res = erl_drv_thread_create((char *)"wxwidgets", - &wxe_thread,wxe_main_loop,NULL,NULL)) == 0) { +#ifdef __DARWIN__ + res = erl_drv_steal_main_thread((char *)"wxwidgets", + &wxe_thread,wxe_main_loop,(void *) sd->pdl,NULL); +#else + res = erl_drv_thread_create((char *)"wxwidgets", + &wxe_thread,wxe_main_loop,(void *) sd->pdl,NULL); +#endif + if(res == 0) { erl_drv_mutex_lock(wxe_status_m); for(;wxe_status == WXE_NOT_INITIATED;) { erl_drv_cond_wait(wxe_status_c, wxe_status_m); @@ -118,7 +138,14 @@ int start_native_gui(wxe_data *sd) void stop_native_gui(wxe_data *sd) { + if(wxe_status == WXE_INITIATED) { + meta_command(WXE_SHUTDOWN, sd); + } +#ifdef __DARWIN__ + erl_drv_stolen_main_thread_join(wxe_thread, NULL); +#else erl_drv_thread_join(wxe_thread, NULL); +#endif erl_drv_mutex_destroy(wxe_status_m); erl_drv_cond_destroy(wxe_status_c); erl_drv_mutex_destroy(wxe_batch_locker_m); @@ -179,12 +206,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; + char * temp = (char *) "Erlang"; + char * argv[] = {temp,NULL}; + ErlDrvPDL pdl = (ErlDrvPDL) vpdl; + + driver_pdl_inc_refc(pdl); // ErlDrvSysInfo einfo; // driver_system_info(&einfo, sizeof(ErlDrvSysInfo)); @@ -199,13 +229,17 @@ 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); +#ifndef __DARWIN__ erl_drv_thread_exit(NULL); +#endif return NULL; } else { erl_drv_mutex_lock(wxe_status_m); 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; } } @@ -260,7 +294,6 @@ bool WxeApp::OnInit() init_nonconsts(global_me, init_caller); erl_drv_mutex_lock(wxe_status_m); wxe_status = WXE_INITIATED; - gl_initiated = FALSE; erl_drv_cond_signal(wxe_status_c); erl_drv_mutex_unlock(wxe_status_m); return TRUE; @@ -401,11 +434,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)) + (memenv && event->caller == memenv->owner)) { switch(event->op) { case WXE_BATCH_END: @@ -456,6 +490,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 +613,7 @@ void WxeApp::destroyMemEnv(wxeMetaCommand& Ecmd) { // } // fflush(stderr); delete memenv; + driver_pdl_dec_refc(Ecmd.pdl); refmap.erase((ErlDrvTermData) Ecmd.port); } @@ -659,7 +697,7 @@ void WxeApp::clearPtr(void * ptr) { send_msg("debug", &msg); } - if(refd->pid != -1) { + if(((int) refd->pid) != -1) { // Send terminate pid to owner wxeReturn rt = wxeReturn(WXE_DRV_PORT,refd->memenv->owner, false); rt.addAtom("_wxe_destroy_"); |