texmacs-dev
[Top][All Lists]
Advanced

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

[Texmacs-dev] Event loop


From: Norbert Nemec
Subject: [Texmacs-dev] Event loop
Date: Sat, 02 May 2009 09:17:41 +0100
User-agent: Thunderbird 2.0.0.21 (X11/20090409)

Hi there,

I have had another look at the Qt event loop and believe there is a fundamental design problem in the TeXmacs event loop that needs to be addressed, probably not only for the Qt gui but for others as well. I will discuss the issue from the Qt-perspective.

As I understand it, there are two independent difficulties to be solved: updating the display and checking for socket&pipe events. Currently, the Qt interface deals with them manually by implementing its own event loop, similar to that in the X11 gui. The socket and pipe events are checked in a busy-wait loop that results in something like 3% CPU load when idle. (on my machine - may be even more on slower machines) and some hacks that - judging by the comments in the sources - do not work as reliable as they should.

A clean solution for the display update could probably be implemented in Qt using the QtTimer class
   http://doc.trolltech.com/4.5/qtimer.html
I attached a very crude attempt to implement this. A the moment, this code does a busy wait at 100% load and crashes at exit, but it demonstrates the idea. Basically, one would want to initiate the timer only when updates need to be done and stop it when all updates are finished. Ultimately, though, I think that the texmacs-gui interface needs to be restructured to allow a clean implementation of this.

The other problem that I see are the socket&pipe listeners called from tm_server_rep::interpose_handler(). Currently these are handled in a busy wait with a small delay. I see three ways to handle this:

a) The straightforward way using again a QtTimer that is called periodically to check for incoming data - still causing some CPU load in idle times. b) The true Qt way, using QtSocket etc. - not portable to other guis, hard to set up. c) The ultimate solution using threads - each thread can block waiting for incoming data.

I am not sure yet what it would mean to use threading only in the Qt interface for this single reason. Introducing multithreading to all of TeXmacs certainly is a tremendous task, but this very limited threads with the single purpose to wait for data coming in on sockets should be possible with far less effort.

These are my thoughts so far. I will look into it a bit further, but I would be happy about any comments.

Greetings,
Norbert
commit 5cdb3ce2b908794a7a67676bd360d9b81b823069
Author: Norbert Nemec <address@hidden>
Date:   Sat May 2 08:45:19 2009 +0100

    Attempt to use Qt event loop

diff --git a/src/src/Plugins/Qt/qt_gui.cpp b/src/src/Plugins/Qt/qt_gui.cpp
index 5f2e4db..712611a 100755
--- a/src/src/Plugins/Qt/qt_gui.cpp
+++ b/src/src/Plugins/Qt/qt_gui.cpp
@@ -45,6 +45,7 @@ qt_gui_rep::qt_gui_rep(int argc2, char **argv2):
   interrupted   = false;
   interrupt_time= texmacs_time ();
   set_output_language (get_locale_language ());
+  guihelper = new QTMGuiHelper(this);
 //  (void) default_font ();
 }
 
@@ -66,6 +67,7 @@ qt_gui_rep::get_max_size (SI& width, SI& height) {
 
 
 qt_gui_rep::~qt_gui_rep()  { 
+  delete guihelper;
 } 
 
 /******************************************************************************
@@ -182,11 +184,20 @@ qt_gui_rep::update () {
 void
 QTMGuiHelper::doUpdate() { 
   gui->update(); 
+  qt_update_flag= false;
 }
 
 void
 qt_gui_rep::event_loop () {
   QApplication *app = (QApplication*) QApplication::instance();
+
+  QTimer *timer = new QTimer( guihelper );
+  QObject::connect( timer, SIGNAL(timeout()), guihelper, SLOT(doUpdate()) );
+  timer->start(0); // 0 ms - call immediately when all other events have been 
processed
+
+  app->exec();
+  delete timer;
+/*
   QTimer t (NULL);
   t.start (25);
 
@@ -204,6 +215,7 @@ qt_gui_rep::event_loop () {
   }
   //FIXME: QCoreApplication sends aboutToQuit signal before exiting...
   app->sendPostedEvents (0, QEvent::DeferredDelete);
+*/
 }
 
 /******************************************************************************
diff --git a/src/src/Plugins/Qt/qt_gui.hpp b/src/src/Plugins/Qt/qt_gui.hpp
index 56ce599..7b692ab 100755
--- a/src/src/Plugins/Qt/qt_gui.hpp
+++ b/src/src/Plugins/Qt/qt_gui.hpp
@@ -27,6 +27,7 @@
 * The qt_gui class
 ******************************************************************************/
 
+class QTMGuiHelper;
 typedef class qt_gui_rep* qt_gui;
 extern qt_gui the_gui;
 
@@ -35,6 +36,7 @@ public:
   bool interrupted;
   time_t interrupt_time;
 
+  QTMGuiHelper *guihelper;
 
   char*                  selection;
   hashmap<string,tree>   selection_t;

reply via email to

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