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); } } } }
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; } }