예제 #1
0
파일: wxe_impl.cpp 프로젝트: AlainODea/otp
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;    
  }
}
예제 #2
0
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);
}
예제 #3
0
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;
    }
}
예제 #4
0
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;
}
예제 #5
0
파일: wxe_impl.cpp 프로젝트: AlainODea/otp
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);
}