texmacs-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Texmacs-dev] Two fixes for delayed execution


From: Norbert Nemec
Subject: [Texmacs-dev] Two fixes for delayed execution
Date: Mon, 12 Oct 2009 18:23:31 +0100
User-agent: Thunderbird 2.0.0.23 (X11/20090817)

Hi there,

I identified two different problems with the delayed execution. One is general, the other Qt-specific

patch 0001:
I once had a segfault during exiting. Turned out that the "static list<SCM> destroy_list" in Guile/Scheme/object.cpp was deleted before the "static array<object> delayed_queue". If the latter still contains objects (which happens once every blue moon) these are added to the former, which does not exist any more. => CRASH. The solution is a new function clear_pending_events which is called before exit(0) in quit. Should be relevant for TeXmacs in general, even though it might be an extremely rare event.

patch 0002:
turns out that a trivial swap of a "<" caused the strange sluggishness with the new delayed execution that I encountered. The fix is just as trivial...

Greetings,
Norbert



>From e75324a558b9eac3af802b3debaad797f560f90b Mon Sep 17 00:00:00 2001
From: Norbert Nemec <address@hidden>
Date: Mon, 12 Oct 2009 14:11:04 +0100
Subject: [PATCH 1/2] Clear pending events before exiting.

---
 src/src/Guile/Scheme/object.cpp      |    7 +++
 src/src/Guile/Scheme/object.hpp      |    1 +
 src/src/Plugins/Qt/qt_gui.cpp        |   72 ++++++++++++++++++---------------
 src/src/Texmacs/Server/tm_server.cpp |    3 +-
 4 files changed, 49 insertions(+), 34 deletions(-)

diff --git a/src/src/Guile/Scheme/object.cpp b/src/src/Guile/Scheme/object.cpp
index b9a5369..ceb0530 100644
--- a/src/src/Guile/Scheme/object.cpp
+++ b/src/src/Guile/Scheme/object.cpp
@@ -413,4 +413,11 @@ exec_pending_commands () {
     }
   }
 }
+
+void
+clear_pending_commands () {
+  delayed_queue= array<object> (0);
+  start_queue= array<int> (0);
+}
+
 #endif // QTTEXMACS
diff --git a/src/src/Guile/Scheme/object.hpp b/src/src/Guile/Scheme/object.hpp
index 0ed81c8..4be726b 100644
--- a/src/src/Guile/Scheme/object.hpp
+++ b/src/src/Guile/Scheme/object.hpp
@@ -147,6 +147,7 @@ bool   exec_file (url u);
 void   exec_delayed (object cmd);
 void   exec_delayed_pause (object cmd);
 void   exec_pending_commands ();
+void   clear_pending_commands ();
 
 object call (const char* fun);
 object call (const char* fun, object a1);
diff --git a/src/src/Plugins/Qt/qt_gui.cpp b/src/src/Plugins/Qt/qt_gui.cpp
index fd29e99..82be74a 100755
--- a/src/src/Plugins/Qt/qt_gui.cpp
+++ b/src/src/Plugins/Qt/qt_gui.cpp
@@ -63,7 +63,7 @@ void
 qt_gui_rep::get_extents (SI& width, SI& height) {
   QDesktopWidget* d= QApplication::desktop();
   int w = d->width();  // returns desktop width
-  int h = d->height(); // returns desktop height        
+  int h = d->height(); // returns desktop height
   width = ((SI) w) * PIXEL;
   height= ((SI) h) * PIXEL;
 }
@@ -121,7 +121,7 @@ qt_gui_rep::get_selection (string key, tree& t, string& s) {
   }
   s= "";
   t= "none";
-  
+
   if (owns) {
     if (selection_t->contains (key)) {
       t= copy (selection_t [key]);
@@ -130,13 +130,13 @@ qt_gui_rep::get_selection (string key, tree& t, string& 
s) {
     }
     return false;
   }
-  
+
   QString originalText = cb->text(mode);
   QByteArray buf = originalText.toAscii();
   if (!(buf.isEmpty())) {
     s << string(buf.constData(), buf.size());
   }
-  
+
   t= tuple ("extern", s);
   return true;
 }
@@ -153,11 +153,11 @@ qt_gui_rep::set_selection (string key, tree t, string s) {
     //XSetSelectionOwner (dpy, XA_PRIMARY, win, CurrentTime);
     //if (XGetSelectionOwner(dpy, XA_PRIMARY)==None) return false;
     selection= as_charp (s);
-        
+
     QClipboard *clipboard = QApplication::clipboard();
     QString originalText = clipboard->text();
-                
-    clipboard->setText(selection);      
+
+    clipboard->setText(selection);
   }
   return true;
 }
@@ -218,23 +218,23 @@ void gui_interpose (void (*r) (void)) { 
the_interpose_handler= r; }
 
 void
 qt_gui_rep::update () {
-  // this is called by doUpdate, which in turns is fired by a timer activated 
in 
+  // this is called by doUpdate, which in turns is fired by a timer activated 
in
   // needs_update, and ensuring that interpose_handler is run during a pass in 
the eventloop
-  // afterwards we reactivate the timer with a pause (see FIXME below) 
-  
+  // afterwards we reactivate the timer with a pause (see FIXME below)
+
   if (the_interpose_handler) the_interpose_handler();
-  
+
   qt_update_flag = false;
-  interrupted = false;  
-  
+  interrupted = false;
+
   updatetimer->start (1000/6);
-  
+
   // FIXME: we need to ensure that the interpose_handler is run at regular 
intervals (1/6th of sec)
-  //        so that informations on the footbar are updated. (this should be 
better handled by 
+  //        so that informations on the footbar are updated. (this should be 
better handled by
   //        promoting code in tm_editor::apply_changes (which is activated 
only after idle periods)
   //        at the level of delayed commands in the gui.
   //        The interval cannot be too small to keep CPU usage low in idle 
state
-} 
+}
 
 
 
@@ -253,29 +253,29 @@ qt_gui_rep::event_loop () {
 static hashmap<socket_notifier,pointer> read_notifiers;
 static hashmap<socket_notifier,pointer> write_notifiers;
 
-void 
+void
 qt_gui_rep::add_notifier (socket_notifier sn)
 {
   QSocketNotifier *qsn;
 
   //  cout << "ADD NOTIFIER" << LF;
-  
+
   // replace any already present notifier
 
   remove_notifier (sn);
 
   // installs both a read and a write notifier (the texmacs interface does not 
specify enough its needs)
-  
-  read_notifiers (sn) = (pointer) (qsn = new QSocketNotifier(sn->fd, 
QSocketNotifier::Read, gui_helper)); 
+
+  read_notifiers (sn) = (pointer) (qsn = new QSocketNotifier(sn->fd, 
QSocketNotifier::Read, gui_helper));
   QObject::connect(qsn, SIGNAL(activated(int)), gui_helper, 
SLOT(doSocketNotification(int)) );
 
   write_notifiers (sn) = (pointer) (qsn = new QSocketNotifier(sn->fd, 
QSocketNotifier::Write, gui_helper));
-  QObject::connect(qsn, SIGNAL(activated(int)), gui_helper, 
SLOT(doSocketNotification(int)) );  
+  QObject::connect(qsn, SIGNAL(activated(int)), gui_helper, 
SLOT(doSocketNotification(int)) );
 }
 
-void 
+void
 qt_gui_rep::remove_notifier (socket_notifier sn)
-{  
+{
   QSocketNotifier *qsn;
 
   //  cout << "REMOVE NOTIFIER" << LF;
@@ -302,8 +302,8 @@ qt_gui_rep::remove_notifier (socket_notifier sn)
  * Delayed commands
  
******************************************************************************/
 
-QTMCommandHelper::QTMCommandHelper (object _cmd, int delay = 0) 
-  : QObject (), cmd (_cmd),  timer () 
+QTMCommandHelper::QTMCommandHelper (object _cmd, int delay = 0)
+  : QObject (), cmd (_cmd),  timer ()
 {
   QObject::connect (&timer, SIGNAL (timeout()), this, SLOT (doCommand()));
   timer.setSingleShot (true);
@@ -316,7 +316,7 @@ QTMCommandHelper::doCommand()
   object obj= call (cmd);
   if (is_int (obj)) {
     timer.start (as_int (obj));
-  } 
+  }
   if (!(timer.isActive ())) deleteLater();
 }
 
@@ -347,14 +347,14 @@ void restart_global_timer (int pause = 0) {
 
 static array <object> delayed_commands;
 
-void   
+void
 exec_delayed (object cmd)
-{ 
+{
  delayed_commands << cmd;
   restart_global_timer ();
 }
 
-void   
+void
 exec_delayed_pause (object cmd)
 {
   delayed_commands << cmd;
@@ -363,9 +363,9 @@ exec_delayed_pause (object cmd)
 
 void   exec_pending_commands ()
 {
-  // guarantee sequential execution of delayed commands 
+  // guarantee sequential execution of delayed commands
   // otherwise some bugs appear in keyboard handling
-  
+
   int i, n= N(delayed_commands);
   for (i=0; i<n; i++) {
     object obj= call (delayed_commands[i]);
@@ -429,6 +429,12 @@ exec_pending_commands () {
     restart_global_timer (lapse);
   }
 }
+
+void
+clear_pending_commands () {
+  delayed_queue= array<object> (0);
+  start_queue= array<int> (0);
+}
 #endif
 
 /******************************************************************************
@@ -534,9 +540,9 @@ set_default_font (string name) {
 
 font
 get_default_font (bool tt) {
-        (void) tt;      
+        (void) tt;
   // get the default font or monospaced font (if tt is true)
-        
+
   // return a null font since this function is not called in the Qt port.
   if (DEBUG_EVENTS) cout << "get_default_font(): SHOULD NOT BE CALLED\n";
   return NULL;
diff --git a/src/src/Texmacs/Server/tm_server.cpp 
b/src/src/Texmacs/Server/tm_server.cpp
index 7e3a671..2fc2968 100644
--- a/src/src/Texmacs/Server/tm_server.cpp
+++ b/src/src/Texmacs/Server/tm_server.cpp
@@ -295,7 +295,7 @@ void
 tm_server_rep::interpose_handler () {
 #ifdef QTTEXMACS
   // TeXmacs/Qt handles delayed messages and socket notification
-  // in its own runloop 
+  // in its own runloop
 #else
 #if 0 // choice between old and new socket listening methods
   listen_to_servers ();
@@ -428,6 +428,7 @@ void
 tm_server_rep::quit () {
   close_all_pipes ();
   call ("quit-TeXmacs-scheme");
+  clear_pending_commands ();
   exit (0);
 }
 
-- 
1.6.3.3

>From 45445c12ca72778458787b8a9acbe9371bfb3fc9 Mon Sep 17 00:00:00 2001
From: Norbert Nemec <address@hidden>
Date: Mon, 12 Oct 2009 18:07:28 +0100
Subject: [PATCH 2/2] Bugfix for delayed execution in Qt

---
 src/src/Plugins/Qt/qt_gui.cpp |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/src/Plugins/Qt/qt_gui.cpp b/src/src/Plugins/Qt/qt_gui.cpp
index 82be74a..bb7b33f 100755
--- a/src/src/Plugins/Qt/qt_gui.cpp
+++ b/src/src/Plugins/Qt/qt_gui.cpp
@@ -421,7 +421,7 @@ exec_pending_commands () {
     int lapse = start_queue[0];
     int n = N(start_queue);
     for (i=1; i<n; i++) {
-      if (lapse < start_queue[i]) lapse = start_queue[i];
+      if (start_queue[i] < lapse) lapse = start_queue[i];
     }
     lapse = lapse - (int) texmacs_time ();
     if (lapse < 0) lapse = 0;
-- 
1.6.3.3


reply via email to

[Prev in Thread] Current Thread [Next in Thread]