aboutsummaryrefslogtreecommitdiffstats
path: root/lib/wx/c_src/wxe_impl.cpp
diff options
context:
space:
mode:
authorDan Gudmundsson <[email protected]>2015-10-20 10:19:16 +0200
committerDan Gudmundsson <[email protected]>2015-11-23 14:39:57 +0100
commite732293edc5a970885d9eb362dcaddf3548f84a4 (patch)
treeae21baeb0c8d65241b7dd55eb02130174bfa00ec /lib/wx/c_src/wxe_impl.cpp
parentba77723f5d81e9e52fb4e2abdffc70ccd3d3e8de (diff)
downloadotp-e732293edc5a970885d9eb362dcaddf3548f84a4.tar.gz
otp-e732293edc5a970885d9eb362dcaddf3548f84a4.tar.bz2
otp-e732293edc5a970885d9eb362dcaddf3548f84a4.zip
wx: Use only one ring buffer for command queue
Avoid copying between command queues, cleaner, faster and safer implementation.
Diffstat (limited to 'lib/wx/c_src/wxe_impl.cpp')
-rw-r--r--lib/wx/c_src/wxe_impl.cpp101
1 files changed, 32 insertions, 69 deletions
diff --git a/lib/wx/c_src/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp
index 5b34f08704..f81d0bbbd9 100644
--- a/lib/wx/c_src/wxe_impl.cpp
+++ b/lib/wx/c_src/wxe_impl.cpp
@@ -57,10 +57,8 @@ extern ErlDrvTermData init_caller;
extern int wxe_status;
wxeFifo * wxe_queue = NULL;
-wxeFifo * wxe_queue_cb_saved = NULL;
unsigned int wxe_needs_signal = 0; // inside batch if larger than 0
-unsigned int wxe_cb_invoked = 0;
/* ************************************************************
* Commands from erlang
@@ -123,11 +121,10 @@ bool WxeApp::OnInit()
{
global_me = new wxeMemEnv();
- wxe_queue = new wxeFifo(1000);
- wxe_queue_cb_saved = new wxeFifo(200);
+ wxe_queue = new wxeFifo(2000);
cb_buff = NULL;
recurse_level = 0;
- delayed_delete = new wxeFifo(10);
+ delayed_delete = new wxeFifo(100);
delayed_cleanup = new wxList;
wxe_ps_init2();
@@ -173,7 +170,6 @@ void WxeApp::shutdown(wxeMetaCommand& Ecmd) {
wxe_status = WXE_EXITING;
ExitMainLoop();
delete wxe_queue;
- delete wxe_queue_cb_saved;
}
void WxeApp::dummy_close(wxEvent& Ev) {
@@ -230,11 +226,10 @@ void handle_event_callback(ErlDrvPort port, ErlDrvTermData process)
// Should we be able to handle commands when recursing? probably
// fprintf(stderr, "\r\nCB EV Start %lu \r\n", process);fflush(stderr);
app->recurse_level++;
- app->dispatch_cb(wxe_queue, wxe_queue_cb_saved, process);
+ app->dispatch_cb(wxe_queue, process);
app->recurse_level--;
// fprintf(stderr, "CB EV done %lu \r\n", process);fflush(stderr);
driver_demonitor_process(port, &monitor);
- wxe_cb_invoked = 1;
}
}
@@ -242,16 +237,11 @@ void WxeApp::dispatch_cmds()
{
if(wxe_status != WXE_INITIATED)
return;
- do {
- wxe_cb_invoked = 0;
- recurse_level++;
- // fprintf(stderr, "\r\ndispatch_saved 0 \r\n");fflush(stderr);
- int level = dispatch(wxe_queue_cb_saved, 0, WXE_STORED);
- // fprintf(stderr, "\r\ndispatch_normal %d\r\n", level);fflush(stderr);
- dispatch(wxe_queue, level, WXE_NORMAL);
- // fprintf(stderr, "\r\ndispatch_done \r\n");fflush(stderr);
- recurse_level--;
- } while(wxe_cb_invoked);
+ recurse_level++;
+ // fprintf(stderr, "\r\ndispatch_normal %d\r\n", level);fflush(stderr);
+ dispatch(wxe_queue);
+ // fprintf(stderr, "\r\ndispatch_done \r\n");fflush(stderr);
+ recurse_level--;
// Cleanup old memenv's and deleted objects
if(recurse_level == 0) {
@@ -260,6 +250,7 @@ void WxeApp::dispatch_cmds()
wxe_dispatch(*curr);
curr->Delete();
}
+ delayed_delete->Cleanup();
if(delayed_cleanup->size() > 0)
for( wxList::compatibility_iterator node = delayed_cleanup->GetFirst();
node;
@@ -269,28 +260,19 @@ void WxeApp::dispatch_cmds()
destroyMemEnv(*event);
delete event;
}
- if(wxe_queue_cb_saved->m_old) {
- driver_free(wxe_queue_cb_saved->m_old);
- wxe_queue_cb_saved->m_old = NULL;
- }
- if(delayed_delete->m_old) {
- driver_free(delayed_delete->m_old);
- delayed_delete->m_old = NULL;
- }
}
}
-int WxeApp::dispatch(wxeFifo * batch, int blevel, int list_type)
+int WxeApp::dispatch(wxeFifo * batch)
{
int ping = 0;
+ int blevel = 0;
wxeCommand *event;
- if(list_type == WXE_NORMAL) erl_drv_mutex_lock(wxe_batch_locker_m);
+ erl_drv_mutex_lock(wxe_batch_locker_m);
while(true) {
while((event = batch->Get()) != NULL) {
- if(list_type == WXE_NORMAL) erl_drv_mutex_unlock(wxe_batch_locker_m);
+ erl_drv_mutex_unlock(wxe_batch_locker_m);
switch(event->op) {
- case -1:
- break;
case WXE_BATCH_END:
{--blevel; }
break;
@@ -321,20 +303,10 @@ int WxeApp::dispatch(wxeFifo * batch, int blevel, int list_type)
break;
}
event->Delete();
- if(list_type == WXE_NORMAL) {
- if(wxe_cb_invoked)
- return blevel;
- else
- erl_drv_mutex_lock(wxe_batch_locker_m);
- }
+ erl_drv_mutex_lock(wxe_batch_locker_m);
+ batch->Cleanup();
}
- if(list_type == WXE_STORED)
- return blevel;
- if(blevel <= 0) { // list_type == WXE_NORMAL
- if(wxe_queue->m_old) {
- driver_free(wxe_queue->m_old);
- wxe_queue->m_old = NULL;
- }
+ if(blevel <= 0) {
erl_drv_mutex_unlock(wxe_batch_locker_m);
return blevel;
}
@@ -348,12 +320,13 @@ int WxeApp::dispatch(wxeFifo * batch, int blevel, int list_type)
}
}
-void WxeApp::dispatch_cb(wxeFifo * batch, wxeFifo * temp, ErlDrvTermData process) {
+void WxeApp::dispatch_cb(wxeFifo * batch, ErlDrvTermData process) {
wxeCommand *event;
+ unsigned int peek;
erl_drv_mutex_lock(wxe_batch_locker_m);
+ peek = batch->Cleanup(batch->cb_start);
while(true) {
- while((event = batch->Get()) != NULL) {
- erl_drv_mutex_unlock(wxe_batch_locker_m);
+ while((event = batch->Peek(&peek)) != NULL) {
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
@@ -361,8 +334,8 @@ void WxeApp::dispatch_cb(wxeFifo * batch, wxeFifo * temp, ErlDrvTermData 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)) {
+ erl_drv_mutex_unlock(wxe_batch_locker_m);
switch(event->op) {
- case -1:
case WXE_BATCH_END:
case WXE_BATCH_BEGIN:
case WXE_DEBUG_PING:
@@ -373,52 +346,42 @@ void WxeApp::dispatch_cb(wxeFifo * batch, wxeFifo * temp, ErlDrvTermData process
memcpy(cb_buff, event->buffer, event->len);
} // continue
case WXE_CB_DIED:
+ batch->cb_start = 0;
event->Delete();
+ erl_drv_mutex_lock(wxe_batch_locker_m);
+ batch->Strip();
+ erl_drv_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:
- size_t start=temp->m_n;
+ batch->cb_start = peek; // In case of recursive callbacks
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);
+ peek = batch->Cleanup(peek);
}
- 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);
+ // peek, batch->m_n);fflush(stderr);
wxe_needs_signal = 1;
- while(batch->m_n == 0) {
+ while(peek >= batch->m_n) {
erl_drv_cond_wait(wxe_batch_locker_c, wxe_batch_locker_m);
+ peek = batch->Cleanup(peek);
}
wxe_needs_signal = 0;
}
}
+
/* Memory handling */
void WxeApp::newMemEnv(wxeMetaCommand& Ecmd) {