Ejemplo n.º 1
0
void WxeApp::dispatch_cb(wxList * batch, wxList * temp, ErlDrvTermData process) {
  int callback_returned = 0;
  while(true) {
    if (batch->size() > 0) {
      for( wxList::compatibility_iterator node = batch->GetFirst();
	   node;
	   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.
	     (memenv && event->caller == memenv->owner)) 
	    {
	      switch(event->op) {
	      case WXE_BATCH_END:
	      case WXE_BATCH_BEGIN:
	      case WXE_DEBUG_PING:
		break;
	      case WXE_CB_RETURN:
		memcpy(cb_buff, event->buffer, event->len);
		callback_returned = 1;
		return;
	      case WXE_CB_START:
		// CB start from now accept message from CB process only
		process = event->caller;
		break;
	      default:
		erl_drv_mutex_unlock(wxe_batch_locker_m);
		if(event->op < OPENGL_START) {
		  // fprintf(stderr, "  cb %d \r\n", event->op);
		  wxe_dispatch(*event);
		} else {
		  gl_dispatch(event->op,event->buffer,event->caller,event->bin);
		}
		erl_drv_mutex_lock(wxe_batch_locker_m);
		break;
		if(callback_returned) 
		  return;
	      }
	      delete event;
	    } else {
	    // fprintf(stderr, "  sav %d \r\n", event->op);
	    temp->Append(event);
	  }
	}
    } else {
      if(callback_returned) {
	return;
      }
      // sleep until something happens
      //fprintf(stderr, "%s:%d sleep %d %d %d %d \r\n", __FILE__, __LINE__, batch->size(), callback_returned, blevel, is_callback);fflush(stderr);
      while(batch->size() == 0) {
	erl_drv_cond_wait(wxe_batch_locker_c, wxe_batch_locker_m);
      }
    }
  }
}
Ejemplo n.º 2
0
void WxeApp::dispatch_cb(wxeFifo * batch, wxeFifo * temp, ErlDrvTermData process) {
  wxeCommand *event;
  erl_drv_mutex_lock(wxe_batch_locker_m);
  while(true) {
    while((event = batch->Get()) != NULL) {
      erl_drv_mutex_unlock(wxe_batch_locker_m);
      wxeMemEnv *memenv = getMemEnv(event->port);
      // 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 || // Event callback start change process
	 event->op == WXE_CB_DIED ||  // Event callback process died
	 // Allow connect_cb during CB i.e. msg from wxe_server.
	 (memenv && event->caller == memenv->owner)) {
	switch(event->op) {
	case -1:
	case WXE_BATCH_END:
	case WXE_BATCH_BEGIN:
	case WXE_DEBUG_PING:
	  break;
	case WXE_CB_RETURN:
	  if(event->len > 0) {
	    cb_buff = (char *) driver_alloc(event->len);
	    memcpy(cb_buff, event->buffer, event->len);
	  }  // continue
	case WXE_CB_DIED:
	  event->Delete();
	  return;
	case WXE_CB_START:
	  // CB start from now accept message from CB process only
	  process = event->caller;
	  break;
	default:
	  size_t start=temp->m_n;
	  if(event->op < OPENGL_START) {
	    // fprintf(stderr, "  cb %d \r\n", event->op);
	    wxe_dispatch(*event);
	  } else {
	    gl_dispatch(event->op,event->buffer,event->caller,event->bin);
	  }
	  if(temp->m_n > start) {
	    erl_drv_mutex_lock(wxe_batch_locker_m);
	    // We have recursed dispatch_cb and messages for this
	    // callback may be saved on temp list move them
	    // to orig list
	    for(unsigned int i=start; i < temp->m_n; i++) {
	      wxeCommand *ev = &temp->m_q[(temp->m_first+i) % temp->m_max];
	      if(ev->caller == process) {
		batch->Append(ev);
	      }
	    }
	    erl_drv_mutex_unlock(wxe_batch_locker_m);
	  }
	  break;
	}
	event->Delete();
      } else {
	// fprintf(stderr, "  save %d %lu\r\n", event->op, event->caller);
	temp->Append(event);
      }
      erl_drv_mutex_lock(wxe_batch_locker_m);
    }
    // sleep until something happens
    // fprintf(stderr, "%s:%d sleep %d %d\r\n", __FILE__, __LINE__,
    //         batch->m_n, temp->m_n);fflush(stderr);
    wxe_needs_signal = 1;
    while(batch->m_n == 0) {
      erl_drv_cond_wait(wxe_batch_locker_c, wxe_batch_locker_m);
    }
    wxe_needs_signal = 0;
  }
}