diff options
author | Dan Gudmundsson <dgud@erlang.org> | 2021-02-19 18:40:07 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-19 18:40:07 +0100 |
commit | 2c976bef44e889355bae7328b9cbf9c738997fb1 (patch) | |
tree | db1616877b5c9f611504f8bcb30cdb8335e4d4bf | |
parent | 8eb2b1aef152c6899185ac4a81dac28c428207ed (diff) | |
parent | 52053235ffe1281c4df5da830a61d85bf4728445 (diff) | |
download | erlang-2c976bef44e889355bae7328b9cbf9c738997fb1.tar.gz |
Merge pull request #4513 from dgud/dgud/wx/fix-queue
dgud/wx/fix queue
-rw-r--r-- | lib/wx/api_gen/wx_extra/wxTaskBarIcon.c_src | 4 | ||||
-rw-r--r-- | lib/wx/c_src/gen/wxe_derived_dest.h | 4 | ||||
-rw-r--r-- | lib/wx/c_src/wxe_callback_impl.cpp | 18 | ||||
-rw-r--r-- | lib/wx/c_src/wxe_gl.cpp | 2 | ||||
-rw-r--r-- | lib/wx/c_src/wxe_helpers.cpp | 209 | ||||
-rw-r--r-- | lib/wx/c_src/wxe_helpers.h | 52 | ||||
-rw-r--r-- | lib/wx/c_src/wxe_impl.cpp | 171 |
7 files changed, 204 insertions, 256 deletions
diff --git a/lib/wx/api_gen/wx_extra/wxTaskBarIcon.c_src b/lib/wx/api_gen/wx_extra/wxTaskBarIcon.c_src index 43221f10a1..21cc460240 100644 --- a/lib/wx/api_gen/wx_extra/wxTaskBarIcon.c_src +++ b/lib/wx/api_gen/wx_extra/wxTaskBarIcon.c_src @@ -21,9 +21,9 @@ <<wxTaskBarIcon_class class EwxTaskBarIcon : public wxTaskBarIcon { public: ~EwxTaskBarIcon() {((WxeApp *)wxTheApp)->clearPtr(this);}; - EwxTaskBarIcon(wxTaskBarIconType iconType) : wxTaskBarIcon(iconType) {}; + EwxTaskBarIcon(wxTaskBarIconType iconType) : wxTaskBarIcon(iconType) { createPopupMenu = 0; }; - int createPopupMenu = 0; + int createPopupMenu; wxe_me_ref *me_ref; private: diff --git a/lib/wx/c_src/gen/wxe_derived_dest.h b/lib/wx/c_src/gen/wxe_derived_dest.h index 33b988eb18..c43ac1335b 100644 --- a/lib/wx/c_src/gen/wxe_derived_dest.h +++ b/lib/wx/c_src/gen/wxe_derived_dest.h @@ -813,9 +813,9 @@ class EwxHtmlWindow : public wxHtmlWindow { class EwxTaskBarIcon : public wxTaskBarIcon { public: ~EwxTaskBarIcon() {((WxeApp *)wxTheApp)->clearPtr(this);}; - EwxTaskBarIcon(wxTaskBarIconType iconType) : wxTaskBarIcon(iconType) {}; + EwxTaskBarIcon(wxTaskBarIconType iconType) : wxTaskBarIcon(iconType) { createPopupMenu = 0; }; - int createPopupMenu = 0; + int createPopupMenu; wxe_me_ref *me_ref; private: diff --git a/lib/wx/c_src/wxe_callback_impl.cpp b/lib/wx/c_src/wxe_callback_impl.cpp index 7b754a0cac..d97b52ed94 100644 --- a/lib/wx/c_src/wxe_callback_impl.cpp +++ b/lib/wx/c_src/wxe_callback_impl.cpp @@ -100,7 +100,7 @@ bool EwxPrintout::OnBeginDocument(int startPage, int endPage) wxeCommand *cb = ((WxeApp *) wxTheApp)->cb_return; int ret_value; if(cb && enif_get_int(cb->env, cb->args[0], &ret_value)) { - cb->Delete(); + delete cb; return ret_value; } } @@ -166,7 +166,7 @@ bool EwxPrintout::HasPage(int page) wxeCommand *cb = ((WxeApp *) wxTheApp)->cb_return; int ret_value; if(cb && enif_get_int(cb->env, cb->args[0], &ret_value)) { - cb->Delete(); + delete cb; return ret_value; } } @@ -183,7 +183,7 @@ bool EwxPrintout::OnPrintPage(int page) wxeCommand *cb = ((WxeApp *) wxTheApp)->cb_return; int ret_value; if(cb && enif_get_int(cb->env, cb->args[0], &ret_value)) { - cb->Delete(); + delete cb; return ret_value; } } @@ -204,7 +204,7 @@ void EwxPrintout::GetPageInfo(int *minPage, int *maxPage, int *pageFrom, int *pa && enif_get_int(cb->env, cb->args[0], pageFrom) && enif_get_int(cb->env, cb->args[0], pageTo) ) { - cb->Delete(); + delete cb; } } wxPrintout::GetPageInfo(minPage, maxPage, pageFrom, pageTo); @@ -224,7 +224,7 @@ wxString EwxListCtrl::OnGetItemText(long item, long col) const { ErlNifBinary bin; if(cb && enif_inspect_binary(cb->env, cb->args[0], &bin)) { wxString str = wxString(bin.data, wxConvUTF8, bin.size); - cb->Delete(); + delete cb; return str; } return wxT("OnGetItemText must return a string"); @@ -241,7 +241,7 @@ wxListItemAttr* EwxListCtrl::OnGetItemAttr(long item) const { wxeCommand *cb = ((WxeApp *) wxTheApp)->cb_return; if(cb) { wxListItemAttr * result = (wxListItemAttr *) memenv->getPtr(cb->env, cb->args[0], "CB item"); - cb->Delete(); + delete cb; return result; } } @@ -262,7 +262,7 @@ int EwxListCtrl::OnGetItemColumnImage(long item, long col) const { wxeCommand *cb = ((WxeApp *) wxTheApp)->cb_return; int ret_value; if(cb && enif_get_int(cb->env, cb->args[0], &ret_value)) { - cb->Delete(); + delete cb; return ret_value; } } @@ -292,7 +292,7 @@ int wxCALLBACK wxEListCtrlCompare(wxeIntPtr item1, wxeIntPtr item2, wxeIntPtr ca wxeCommand *cb = ((WxeApp *) wxTheApp)->cb_return; int ret_value; if(cb && enif_get_int(cb->env, cb->args[0], &ret_value)) { - cb->Delete(); + delete cb; return ret_value; } } @@ -314,7 +314,7 @@ wxMenu* EwxTaskBarIcon::CreatePopupMenu() { wxeCommand *cb = ((WxeApp *) wxTheApp)->cb_return; wxMenu * ret_value; if(cb && (ret_value = (wxMenu *) memenv->getPtr(cb->env, cb->args[0], "menu"))) { - cb->Delete(); + delete cb; return ret_value; } } diff --git a/lib/wx/c_src/wxe_gl.cpp b/lib/wx/c_src/wxe_gl.cpp index 87b8bf4f46..c527926940 100644 --- a/lib/wx/c_src/wxe_gl.cpp +++ b/lib/wx/c_src/wxe_gl.cpp @@ -112,7 +112,6 @@ void no_context(wxeCommand *event) { enif_make_atom(event->env, "_egl_error_"), enif_make_int(event->env, event->op), enif_make_atom(event->env, "no_gl_context"))); - event->op = -1; enif_clear_env(event->env); } @@ -148,7 +147,6 @@ void gl_dispatch(wxeCommand *event) { enif_make_int(event->env, event->op), enif_make_atom(event->env, "undef"))); } - event->op = -1; enif_clear_env(event->env); } diff --git a/lib/wx/c_src/wxe_helpers.cpp b/lib/wx/c_src/wxe_helpers.cpp index 1f1fd0964b..e4d23806e6 100644 --- a/lib/wx/c_src/wxe_helpers.cpp +++ b/lib/wx/c_src/wxe_helpers.cpp @@ -27,188 +27,115 @@ wxeCommand::wxeCommand() { + env = enif_alloc_env(); } wxeCommand::~wxeCommand() { - Delete(); + if(env) + enif_free_env(env); } -void wxeCommand::Delete() +void wxeCommand::Init(int u_argc, const ERL_NIF_TERM u_argv[], int u_op, wxe_me_ref *u_mr, ErlNifPid u_caller) { - op = -2; - enif_clear_env(env); + op = u_op; + caller = u_caller; + + argc = u_argc; + for(int i=0; i<argc; i++) + args[i] = enif_make_copy(env, u_argv[i]); + me_ref = u_mr; } + /* **************************************************************************** * wxeFifo * ****************************************************************************/ wxeFifo::wxeFifo(unsigned int sz) { - m_q = (wxeCommand *) enif_alloc(sizeof(wxeCommand) * sz); - m_orig_sz = sz; - m_max = sz; - m_n = 0; - m_first = 0; - cb_start = 0; - m_old = NULL; - for(unsigned int i = 0; i < sz; i++) { - m_q[i].op = -1; - m_q[i].env = enif_alloc_env(); - } + size = 0; } wxeFifo::~wxeFifo() { - // dealloc all memory buffers - for(unsigned int i=0; i < m_max; i++) { - enif_free_env(m_q[i].env); + + for(std::deque<wxeCommand *>::iterator it = m_q.begin(); it != m_q.end(); ++it) { + delete *it; } - enif_free(m_q); -} -wxeCommand * wxeFifo::Get() -{ - unsigned int pos; - do { - if(m_n <= 0) - return NULL; + for(std::vector<wxeCommand *>::iterator it = free.begin(); it != free.end(); ++it) { + delete *it; + } - pos = m_first++; - m_n--; - m_first %= m_max; - } while(m_q[pos].op < 0); - return &m_q[pos]; } -wxeCommand * wxeFifo::Peek(unsigned int *i) +wxeCommand * wxeFifo::Get() { - unsigned int pos; + wxeCommand * cmd; do { - if(*i >= m_n || m_n <= 0) + if(m_q.empty()) return NULL; - pos = (m_first+*i) % m_max; - (*i)++; - } while(m_q[pos].op < 0); - return &m_q[pos]; + else { + cmd = m_q.front(); + m_q.pop_front(); + } + } while (cmd == NULL); + size--; + return cmd; } -int wxeFifo::Add(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[], int op, wxe_me_ref *mr, ErlNifPid caller) +int wxeFifo::Add(int argc, const ERL_NIF_TERM argv[], int op, wxe_me_ref *mr, ErlNifPid caller) { - int i; - unsigned int pos; - wxeCommand *curr; - - if(m_n == (m_max-1)) { // resize - Realloc(); + wxeCommand * curr; + if(free.empty()) { + curr = new wxeCommand(); + } else { + curr = free.back(); + free.pop_back(); } - - pos = (m_first + m_n) % m_max; - m_n++; - - curr = &m_q[pos]; - curr->op = op; - curr->caller = caller; - - curr->argc = argc; - for(i=0; i<argc; i++) - curr->args[i] = enif_make_copy(curr->env, argv[i]); - - curr->me_ref = mr; - return m_n; + curr->Init(argc, argv, op, mr, caller); + m_q.push_back(curr); + size++; + return size; } -void wxeFifo::Append(wxeCommand *orig) +void wxeFifo::DelQueue(unsigned int i) { - unsigned int pos; - wxeCommand *curr; - ErlNifEnv *temp; - if(m_n == (m_max-1)) { // resize - Realloc(); - } - - pos = (m_first + m_n) % m_max; - m_n++; - - curr = &m_q[pos]; - curr->op = orig->op; - if(curr->op == -1) return; - curr->caller = orig->caller; - - temp = orig->env; - orig->env = curr->env; - curr->env = temp; - - curr->argc = orig->argc; - for(int i=0; i < 16; i++) { - curr->args[i] = orig->args[i]; - } - curr->me_ref = orig->me_ref; - orig->op = -1; + size--; + m_q[i] = NULL; } -void wxeFifo::Realloc() + +void wxeFifo::DeleteCmd(wxeCommand *orig) { - unsigned int i, j; - unsigned int growth = m_orig_sz / 2; - unsigned int new_sz = growth + m_max; - unsigned int max = m_max; - unsigned int first = m_first; - unsigned int n = m_n; - wxeCommand * old = m_q; - wxeCommand * queue = (wxeCommand *)enif_alloc(new_sz*sizeof(wxeCommand)); - - // fprintf(stderr, "\r\nrealloc qsz %d\r\n", new_sz);fflush(stderr); - - m_max=new_sz; - m_first = 0; - m_n=0; - m_q = queue; - - for(i=0; i < new_sz; i++) { - m_q[i].env = NULL; - } - for(i=0; i < n; i++) { - unsigned int pos = (i+first)%max; - if(old[pos].op >= 0) - Append(&old[pos]); - } - // Optimize later - for(i=0, j=m_n; i < n; i++) { - if(old[i].env) - m_q[j++].env = old[i].env; - } - for(i = m_n; i < new_sz; i++) { // Reset the rest - m_q[i].op = -1; - if(!m_q[i].env) - m_q[i].env = enif_alloc_env(); - } - for(i=0; i < new_sz; i++) { - if(m_q[i].env == NULL) { - fprintf(stderr, "i %d \r\n", i); - fflush(stderr); - abort(); - } - } - // Can not free old queue here it can be used in the wx thread - m_old = old; + orig->op = -2; // Assert: will crash if op is negativ + enif_clear_env(orig->env); + free.push_back(orig); } -// Strip end of queue if ops are already taken care of, avoids reallocs -void wxeFifo::Strip() +unsigned int wxeFifo::Size() { - while((m_n > 0) && (m_q[(m_first + m_n - 1)%m_max].op < -1)) { - m_n--; - } + return size; } -unsigned int wxeFifo::Cleanup(unsigned int def) +void wxeFifo::Append(wxeCommand *orig) { - if(m_old) { - enif_free(m_old); - m_old = NULL; - // Realloced we need to start from the beginning - return 0; + wxeCommand * curr; + if(free.empty()) { + curr = new wxeCommand(); } else { - return def < cb_start? def : cb_start; + curr = free.back(); + free.pop_back(); } + + curr->op = orig->op; + curr->caller = orig->caller; + curr->argc = orig->argc; + for(int i=0; i<curr->argc; i++) + curr->args[i] = orig->args[i]; + ErlNifEnv * temp = curr->env; + curr->env = orig->env; + orig->env = temp; + curr->me_ref = orig->me_ref; + orig->op = -1; // Assert: will crash if op is negativ + m_q.push_back(curr); } diff --git a/lib/wx/c_src/wxe_helpers.h b/lib/wx/c_src/wxe_helpers.h index 38cbb6f25c..6fea3033c0 100644 --- a/lib/wx/c_src/wxe_helpers.h +++ b/lib/wx/c_src/wxe_helpers.h @@ -22,6 +22,8 @@ #define _WXE_HELPER_H #include "wxe_memory.h" +#include <vector> +#include <deque> DECLARE_EVENT_TYPE(wxeEVT_META_COMMAND, -1) @@ -44,42 +46,34 @@ class wxeMetaCommand : public wxEvent class wxeCommand { public: - wxeCommand(); - virtual ~wxeCommand(); // Use Delete() - - wxeCommand * Save(int Op) { op = Op; return this; }; - void Delete(); - - ErlNifPid caller; - int op; - ErlNifEnv *env; - int argc; - ERL_NIF_TERM args[16]; - wxe_me_ref * me_ref; + wxeCommand(); + virtual ~wxeCommand(); + void Init(int argc, const ERL_NIF_TERM argv[], int op, wxe_me_ref *mr, ErlNifPid caller); + + ErlNifPid caller; + int op; + ErlNifEnv *env; + int argc; + ERL_NIF_TERM args[16]; + wxe_me_ref * me_ref; }; class wxeFifo { public: - wxeFifo(unsigned int size); - virtual ~wxeFifo(); - - int Add(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[], int, wxe_me_ref *, ErlNifPid caller); - void Append(wxeCommand *Other); + wxeFifo(unsigned int size); + virtual ~wxeFifo(); - wxeCommand * Get(); - wxeCommand * Peek(unsigned int *item); + int Add(int argc, const ERL_NIF_TERM argv[], int, wxe_me_ref *, ErlNifPid caller); + void Append(wxeCommand *Other); + void DelQueue(unsigned int it); + void DeleteCmd(wxeCommand *); + unsigned int Size(); - void Realloc(); - void Strip(); - unsigned int Cleanup(unsigned int peek=0); + wxeCommand * Get(); - unsigned int cb_start; - unsigned int m_max; - unsigned int m_first; - unsigned int m_n; - unsigned int m_orig_sz; - wxeCommand *m_q; - wxeCommand *m_old; + std::deque <wxeCommand *> m_q; + std::vector <wxeCommand *> free; + unsigned int size; // keep own counter list::size() is not O(1) in old impl }; class wxeErlTerm : public wxClientData diff --git a/lib/wx/c_src/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp index 5e5130a4d0..4a355bc180 100644 --- a/lib/wx/c_src/wxe_impl.cpp +++ b/lib/wx/c_src/wxe_impl.cpp @@ -58,6 +58,7 @@ extern int wxe_status; wxeFifo * wxe_queue = NULL; +unsigned int wxe_idle_processed = 0; unsigned int wxe_needs_signal = 0; // inside batch if larger than 0 unsigned int wxe_needs_wakeup = 0; // inside batch if larger than 0 @@ -74,7 +75,7 @@ void push_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[], int op, wxe_m } enif_mutex_lock(wxe_batch_locker_m); - int n = wxe_queue->Add(env, argc, argv, op, mp, caller); + int n = wxe_queue->Add(argc, argv, op, mp, caller); if(wxe_needs_signal) { enif_cond_signal(wxe_batch_locker_c); @@ -115,6 +116,21 @@ void send_msg(const char * type, const wxString * msg) { rt.send(emsg); } +void print_cmd(wxeCommand& event) +{ + int i; + wxe_fns_t *func = &wxe_fns[event.op]; + enif_fprintf(stderr, " %T %d %s::%s(", event.caller, event.op, func->cname, func->fname); + for(i=0; i < event.argc-1; i++) { + enif_fprintf(stderr, "%T,", event.args[i]); + } + if(i > 0) { + enif_fprintf(stderr, "%T)\r\n", event.args[i]); + } else { + enif_fprintf(stderr, ")\r\n"); + } +} + /* ************************************************************ * Init WxeApp the application emulator * ************************************************************/ @@ -245,7 +261,6 @@ int WxeApp::dispatch_cmds() return more; recurse_level++; // fprintf(stderr, "\r\ndispatch_normal %d\r\n", recurse_level);fflush(stderr); - wxe_queue->cb_start = 0; more = dispatch(wxe_queue); // fprintf(stderr, "\r\ndispatch_done %d\r\n", recurse_level);fflush(stderr); recurse_level--; @@ -255,9 +270,9 @@ int WxeApp::dispatch_cmds() wxeCommand *curr; while((curr = delayed_delete->Get()) != NULL) { wxe_dispatch(*curr); - curr->Delete(); + delayed_delete->DeleteCmd(curr); } - delayed_delete->Cleanup(); + // delayed_delete->Cleanup(); if(delayed_cleanup->size() > 0) for( wxList::compatibility_iterator node = delayed_cleanup->GetFirst(); node; @@ -280,10 +295,10 @@ int WxeApp::dispatch(wxeFifo * batch) int wait = 0; // Let event handling generate events sometime wxeCommand *event; enif_mutex_lock(wxe_batch_locker_m); + wxe_idle_processed = 1; while(true) { while((event = batch->Get()) != NULL) { wait += 1; - enif_mutex_unlock(wxe_batch_locker_m); switch(event->op) { case WXE_BATCH_END: if(blevel>0) { @@ -307,25 +322,28 @@ int WxeApp::dispatch(wxeFifo * batch) break; case WXE_CB_RETURN: if(enif_is_identical(event->args[0], WXE_ATOM_ok)) { - event->Delete(); + batch->DeleteCmd(event); } else { cb_return = event; // must be deleted after taken care of } + enif_mutex_unlock(wxe_batch_locker_m); return 1; default: + enif_mutex_unlock(wxe_batch_locker_m); if(event->op < OPENGL_START) { // fprintf(stderr, " c %d (%d) \r\n", event->op, blevel); wxe_dispatch(*event); } else { gl_dispatch(event); } + enif_mutex_lock(wxe_batch_locker_m); break; } - event->Delete(); - if(wait > CHECK_EVENTS) + if(wait > CHECK_EVENTS) { + enif_mutex_unlock(wxe_batch_locker_m); return 1; // Let wx check for events - enif_mutex_lock(wxe_batch_locker_m); - batch->Cleanup(); + } + batch->DeleteCmd(event); } if(blevel <= 0) { enif_mutex_unlock(wxe_batch_locker_m); @@ -334,7 +352,7 @@ int WxeApp::dispatch(wxeFifo * batch) // sleep until something happens // fprintf(stderr, "%s:%d sleep %d %d %d\r\n", __FILE__, __LINE__, batch->m_n, blevel, wait);fflush(stderr); wxe_needs_signal = 1; - while(batch->m_n == 0) { + while(batch->m_q.empty()) { enif_cond_wait(wxe_batch_locker_c, wxe_batch_locker_m); } wxe_needs_signal = 0; @@ -343,71 +361,86 @@ int WxeApp::dispatch(wxeFifo * batch) void WxeApp::dispatch_cb(wxeFifo * batch, wxeMemEnv * memenv, ErlNifPid process) { wxeCommand *event; - unsigned int peek; + unsigned int peek = 0; enif_mutex_lock(wxe_batch_locker_m); - peek = batch->Cleanup(batch->cb_start); + unsigned int i = 0; + unsigned int last = batch->m_q.size(); + wxe_idle_processed = 0; while(true) { - while((event = batch->Peek(&peek)) != NULL) { - // enif_fprintf(stderr, " CB %T %d \r\n", event->caller, event->op); - if(event->op == WXE_CB_START || // Event callback start change process - event->op == WXE_CB_DIED || // Event callback process died - enif_compare_pids(&event->caller, &process) == 0 || // Callbacks from CB process only - // Allow connect_cb during CB i.e. msg from wxe_server. - (memenv && enif_compare_pids(&event->caller,&memenv->owner) == 0)) { - enif_mutex_unlock(wxe_batch_locker_m); - switch(event->op) { - case WXE_BATCH_END: - case WXE_BATCH_BEGIN: - case WXE_DEBUG_PING: - break; - case WXE_CB_RETURN: - if(enif_is_identical(event->args[0], WXE_ATOM_ok)) { - event->Delete(); - } else { - cb_return = event; // must be deleted after taken care of + + while (i < last ) { + event = batch->m_q[i]; + // enif_fprintf(stderr, "%d: CB %T owner %T it %d %d (%d) \r\n", + // recurse_level, event ? event->caller : process, process, + // i, batch->Size(), batch->m_q.size()); + if(event && + (event->op == WXE_CB_START || // Event callback start change process + event->op == WXE_CB_DIED || // Event callback process died + event->op == WXE_DEBUG_PING || + enif_compare_pids(&event->caller, &process) == 0 || // Callbacks from CB process only + // Allow connect_cb during CB i.e. msg from wxe_server. + (memenv && enif_compare_pids(&event->caller,&memenv->owner) == 0) + )) + { + // enif_fprintf(stderr, "Exec:"); print_cmd(*event); + batch->DelQueue(i); + switch(event->op) { + case WXE_BATCH_END: + case WXE_BATCH_BEGIN: + case WXE_DEBUG_PING: + break; + case WXE_CB_RETURN: + if(enif_is_identical(event->args[0], WXE_ATOM_ok)) { + batch->DeleteCmd(event); + } else { + cb_return = event; // must be deleted after taken care of + } + wxe_needs_wakeup = 1; + enif_mutex_unlock(wxe_batch_locker_m); + return; + case WXE_CB_DIED: + cb_return = NULL; + batch->DeleteCmd(event); + wxe_needs_wakeup = 1; + enif_mutex_unlock(wxe_batch_locker_m); + return; + case WXE_CB_START: + // CB start from now accept message from CB process only + process = event->caller; + break; + default: + enif_mutex_unlock(wxe_batch_locker_m); + if(event->op < OPENGL_START) { + wxe_dispatch(*event); + } else { + gl_dispatch(event); + } + enif_mutex_lock(wxe_batch_locker_m); + last = batch->m_q.size(); + if(wxe_idle_processed) { + // We have processed cmds inside dispatch() + // so the iterator may be wrong, restart from + // beginning of the queue + i = 0; + } + break; } - batch->cb_start = 0; - enif_mutex_lock(wxe_batch_locker_m); - batch->Strip(); - wxe_needs_wakeup = 1; - enif_mutex_unlock(wxe_batch_locker_m); - return; - case WXE_CB_DIED: - cb_return = NULL; - batch->cb_start = 0; - event->Delete(); - enif_mutex_lock(wxe_batch_locker_m); - batch->Strip(); - wxe_needs_wakeup = 1; - enif_mutex_unlock(wxe_batch_locker_m); - return; - case WXE_CB_START: - // CB start from now accept message from CB process only - process = event->caller; - break; - default: - batch->cb_start = peek; // In case of recursive callbacks - if(event->op < OPENGL_START) { - wxe_dispatch(*event); - } else { - gl_dispatch(event); - } - break; - } - event->Delete(); - enif_mutex_lock(wxe_batch_locker_m); - peek = batch->Cleanup(peek); + batch->DeleteCmd(event); + } else { + // enif_fprintf(stderr, "Ignore:"); event ? print_cmd(*event) : fprintf(stderr, "NULL\r\n"); } + i++; } // sleep until something happens - // fprintf(stderr, "%s:%d sleep %d %d\r\n", __FILE__, __LINE__, - // peek, batch->m_n);fflush(stderr); + // enif_fprintf(stderr, "\r\n%s:%d: %d: sleep sz %d (%d) it pos: %d\r\n", __FILE__, __LINE__, recurse_level, + // batch->Size(), batch->m_q.size(), i); fflush(stderr); wxe_needs_signal = 1; - while(peek >= batch->m_n) { + peek = batch->Size(); + while(peek >= batch->Size()) { enif_cond_wait(wxe_batch_locker_c, wxe_batch_locker_m); - peek = batch->Cleanup(peek); } wxe_needs_signal = 0; + last = batch->m_q.size(); } } @@ -419,14 +452,10 @@ void WxeApp::wxe_dispatch(wxeCommand& event) void (*nif_cb) (WxeApp *, wxeMemEnv *, wxeCommand& ) = func->nif_cb; wxeMemEnv * memenv = (wxeMemEnv *) event.me_ref->memenv; if(wxe_debug) { - enif_fprintf(stderr, "%T %d %s::%s(", event.caller, op, func->cname, func->fname); - for(int i=0; i < event.argc; i++) - enif_fprintf(stderr, "%T,", event.args[i]); - enif_fprintf(stderr, ") %p\r\n", memenv); + print_cmd(event); } if (event.me_ref->memenv) { if(nif_cb) { - event.op = -1; try { nif_cb(this, memenv, event); } catch (wxe_badarg badarg) { wxeReturn rt = wxeReturn(memenv, event.caller, false); |