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)); // Disable floating point execption if they are on. // This should be done in emulator but it's not in yet. #ifndef _WIN32 erts_thread_disable_fpe(); #endif result = wxEntry(argc, argv); // fprintf(stderr, "WXWidgets quits main loop %d \r\n", result); 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 { 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; } }
static ERTS_INLINE void call_async_ready(ErtsAsync *a) { #if ERTS_USE_ASYNC_READY_Q Port *p = erts_id2port_sflgs(a->port, NULL, 0, ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP); #else Port *p = erts_thr_id2port_sflgs(a->port, ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP); #endif if (!p) { if (a->async_free) a->async_free(a->async_data); } else { if (async_ready(p, a->async_data)) { if (a->async_free) a->async_free(a->async_data); } #if ERTS_USE_ASYNC_READY_Q erts_port_release(p); #else erts_thr_port_release(p); #endif } if (a->pdl) driver_pdl_dec_refc(a->pdl); if (a->hndl) erts_ddll_dereference_driver(a->hndl); }
void *wxe_main_loop(void *vpdl) { int result; int argc = 1; char * temp = (char *) "Erlang"; char * argv[] = {temp,NULL}; ErlDrvPDL pdl = (ErlDrvPDL) vpdl; driver_pdl_inc_refc(pdl); // Disable floating point execption if they are on. // This should be done in emulator but it's not in yet. #ifndef _WIN32 erts_thread_disable_fpe(); #else // Setup that wxWidgets should look for cursors and icons in // this dll and not in werl.exe (which is the default) HMODULE WXEHandle = GetModuleHandle(_T("wxe_driver")); wxSetInstance((HINSTANCE) WXEHandle); #endif wxe_ps_init(); result = wxEntry(argc, argv); // fprintf(stderr, "WXWidgets quits main loop %d \r\n", result); 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; } }
static void* async_main(void* arg) { AsyncQueue* q = (AsyncQueue*) arg; #ifdef ERTS_ENABLE_LOCK_CHECK { char buf[27]; erts_snprintf(&buf[0], 27, "async %d", q->no); erts_lc_set_thread_name(&buf[0]); } #endif while(1) { ErlAsync* a = async_get(q); if (a->port == NIL) { /* TIME TO DIE SIGNAL */ erts_free(ERTS_ALC_T_ASYNC, (void *) a); break; } else { (*a->async_invoke)(a->async_data); /* Major problem if the code for async_invoke or async_free is removed during a blocking operation */ #ifdef ERTS_SMP { Port *p; p = erts_id2port_sflgs(a->port, NULL, 0, ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP); if (!p) { if (a->async_free) (*a->async_free)(a->async_data); } else { if (async_ready(p, a->async_data)) { if (a->async_free) (*a->async_free)(a->async_data); } async_detach(a->hndl); erts_port_release(p); } if (a->pdl) { driver_pdl_dec_refc(a->pdl); } erts_free(ERTS_ALC_T_ASYNC, (void *) a); } #else if (a->pdl) { driver_pdl_dec_refc(a->pdl); } erts_mtx_lock(&async_ready_mtx); a->next = async_ready_list; async_ready_list = a; erts_mtx_unlock(&async_ready_mtx); sys_async_ready(q->hndl); #endif } } return NULL; }
void WxeApp::destroyMemEnv(wxeMetaCommand& Ecmd) { // Clear incoming cmd queue first // dispatch_cmds(); wxWindow *parent = NULL; wxeMemEnv * memenv = refmap[(ErlDrvTermData) Ecmd.port]; if(wxe_debug) { wxString msg; msg.Printf(wxT("Destroying all memory ")); send_msg("debug", &msg); } // pre-pass delete all dialogs first since they might crash erlang otherwise for(int i=1; i < memenv->next; i++) { wxObject * ptr = (wxObject *) memenv->ref2ptr[i]; if(ptr) { ptrMap::iterator it = ptr2ref.find(ptr); if(it != ptr2ref.end()) { wxeRefData *refd = it->second; if(refd->alloc_in_erl) { if(refd->type == 2) { wxDialog *win = (wxDialog *) ptr; if(win->IsModal()) { win->EndModal(-1); } parent = win->GetParent(); if(parent) { ptrMap::iterator parentRef = ptr2ref.find(parent); if(parentRef == ptr2ref.end()) { // The parent is already dead delete the parent ref win->SetParent(NULL); } } delete win; } } } } } // First pass, delete all top parents/windows of all linked objects // fprintf(stderr, "close port %x\r\n", Ecmd.port);fflush(stderr); for(int i=1; i < memenv->next; i++) { void * ptr = memenv->ref2ptr[i]; if(ptr) { ptrMap::iterator it = ptr2ref.find(ptr); if(it != ptr2ref.end()) { wxeRefData *refd = it->second; if(refd->alloc_in_erl && refd->type == 0) { parent = (wxWindow *) ptr; // fprintf(stderr, "window %x %d\r\n", (int) parent, refd->ref); while(parent->GetParent()) { parent = parent->GetParent(); // fprintf(stderr, " parent %x \r\n", (int) parent); } ptrMap::iterator pdata = ptr2ref.find(parent); if(pdata != ptr2ref.end()) { delete parent; } // else parent is already deleted } } else { // fprintf(stderr, "Error found no ref in %d => %x\r\n", i, ptr); } } } // Second pass delete everything else allocated // everything linked from windows should now be deleted for(int i=1; i < memenv->next; i++) { void * ptr = memenv->ref2ptr[i]; if(ptr) { ptrMap::iterator it = ptr2ref.find(ptr); if(it != ptr2ref.end()) { wxeRefData *refd = it->second; if(refd->alloc_in_erl) { int type = refd->type; if((refd->type == 1) && ((wxObject *)ptr)->IsKindOf(CLASSINFO(wxBufferedDC))) { ((wxBufferedDC *)ptr)->m_dc = NULL; // Workaround } wxString msg; if((refd->type == 0)) { // Maybe also class 1 wxClassInfo *cinfo = ((wxObject *)ptr)->GetClassInfo(); msg.Printf(wxT("Memory leak: {wx_ref, %d, %s}"), refd->ref, cinfo->GetClassName()); send_msg("error", &msg); } else { delete_object(ptr, refd); } if(type == 0 || type > 3) { // Delete refs for leaks and non overridden allocs delete refd; ptr2ref.erase(it); } // overridden allocs deletes meta-data in clearPtr } else { // Not alloced in erl just delete references if(refd->ref >= global_me->next) { // if it is not part of global ptrs delete refd; ptr2ref.erase(it); } } } } } // Assert ? // for(ptrMap::iterator it = ptr2ref.begin(); it != ptr2ref.end(); it++) { // wxeRefData *refd = it->second; // if(refd->ref >= global_me->next) // fprintf(stderr, "L %d %d\r\n", refd->ref, refd->alloc_in_erl); // } // fflush(stderr); delete memenv; driver_pdl_dec_refc(Ecmd.pdl); refmap.erase((ErlDrvTermData) Ecmd.port); }