summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Gudmundsson <dgud@erlang.org>2021-02-19 18:40:07 +0100
committerGitHub <noreply@github.com>2021-02-19 18:40:07 +0100
commit2c976bef44e889355bae7328b9cbf9c738997fb1 (patch)
treedb1616877b5c9f611504f8bcb30cdb8335e4d4bf
parent8eb2b1aef152c6899185ac4a81dac28c428207ed (diff)
parent52053235ffe1281c4df5da830a61d85bf4728445 (diff)
downloaderlang-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_src4
-rw-r--r--lib/wx/c_src/gen/wxe_derived_dest.h4
-rw-r--r--lib/wx/c_src/wxe_callback_impl.cpp18
-rw-r--r--lib/wx/c_src/wxe_gl.cpp2
-rw-r--r--lib/wx/c_src/wxe_helpers.cpp209
-rw-r--r--lib/wx/c_src/wxe_helpers.h52
-rw-r--r--lib/wx/c_src/wxe_impl.cpp171
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);