diff mbox

[2/3] console: rework text terminal cursor logic

Message ID 1400756406-22617-3-git-send-email-kraxel@redhat.com
State New
Headers show

Commit Message

Gerd Hoffmann May 22, 2014, 11 a.m. UTC
Have a global timer.  Update all visible terminal windows syncronously.
Right now this can be the active_console only, but that will change
soon.  The global timer will disable itself if not needed, so we only
have to care start it if needed.  Which might be at console switch time
or when a new displaychangelistener is registered.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/console.c | 50 ++++++++++++++++++++++++++++++++------------------
 1 file changed, 32 insertions(+), 18 deletions(-)

Comments

Ian Campbell June 8, 2014, 10:30 a.m. UTC | #1
On Thu, 2014-05-22 at 13:00 +0200, Gerd Hoffmann wrote:
> Have a global timer.  Update all visible terminal windows syncronously.
> Right now this can be the active_console only, but that will change
> soon.  The global timer will disable itself if not needed, so we only
> have to care start it if needed.  Which might be at console switch time
> or when a new displaychangelistener is registered.

Running current master (d7d3d6092cb7) I'm seeing a segmentation fault
while running:
        ./aarch64-softmmu/qemu-system-aarch64 -M virt -cpu cortex-a57
        -sdl
which goes away if I revert this patch. qemu is configured with
        ./configure --target-list=aarch64-softmmu  --enable-sdl

The backtrace shows that the timer is NULL.

Program received signal SIGSEGV, Segmentation fault.
0x0000555555778204 in timer_mod (ts=0x0, expire_time=662170703) at qemu-timer.c:442
442	    timer_mod_ns(ts, expire_time * ts->scale);
(gdb) bt
#0  0x0000555555778204 in timer_mod (ts=0x0, expire_time=662170703) at qemu-timer.c:442
#1  0x0000555555796130 in text_console_update_cursor_timer () at ui/console.c:1703
#2  text_console_update_cursor (opaque=opaque@entry=0x0) at ui/console.c:1725
#3  0x0000555555798feb in register_displaychangelistener (dcl=<optimized out>) at ui/console.c:1316
#4  0x00005555557a250f in sdl_display_init (ds=ds@entry=0x5555564c0d00, full_screen=-446133248, no_frame=<optimized out>)
    at ui/sdl.c:946
#5  0x00005555555f50a7 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at vl.c:4475

Cheers,
Ian.
Gerd Hoffmann June 10, 2014, 7:44 a.m. UTC | #2
On So, 2014-06-08 at 11:30 +0100, Ian Campbell wrote:
> On Thu, 2014-05-22 at 13:00 +0200, Gerd Hoffmann wrote:
> > Have a global timer.  Update all visible terminal windows syncronously.
> > Right now this can be the active_console only, but that will change
> > soon.  The global timer will disable itself if not needed, so we only
> > have to care start it if needed.  Which might be at console switch time
> > or when a new displaychangelistener is registered.
> 
> Running current master (d7d3d6092cb7) I'm seeing a segmentation fault
> while running:
>         ./aarch64-softmmu/qemu-system-aarch64 -M virt -cpu cortex-a57
>         -sdl
> which goes away if I revert this patch. qemu is configured with
>         ./configure --target-list=aarch64-softmmu  --enable-sdl
> 
> The backtrace shows that the timer is NULL.

http://lists.gnu.org/archive/html/qemu-devel/2014-06/msg00106.html

High time to get the pull request out of the door ...

cheers,
  Gerd
Ian Campbell June 11, 2014, 9:59 a.m. UTC | #3
On Tue, 2014-06-10 at 09:44 +0200, Gerd Hoffmann wrote:
> On So, 2014-06-08 at 11:30 +0100, Ian Campbell wrote:
> > On Thu, 2014-05-22 at 13:00 +0200, Gerd Hoffmann wrote:
> > > Have a global timer.  Update all visible terminal windows syncronously.
> > > Right now this can be the active_console only, but that will change
> > > soon.  The global timer will disable itself if not needed, so we only
> > > have to care start it if needed.  Which might be at console switch time
> > > or when a new displaychangelistener is registered.
> > 
> > Running current master (d7d3d6092cb7) I'm seeing a segmentation fault
> > while running:
> >         ./aarch64-softmmu/qemu-system-aarch64 -M virt -cpu cortex-a57
> >         -sdl
> > which goes away if I revert this patch. qemu is configured with
> >         ./configure --target-list=aarch64-softmmu  --enable-sdl
> > 
> > The backtrace shows that the timer is NULL.
> 
> http://lists.gnu.org/archive/html/qemu-devel/2014-06/msg00106.html

Aha, thanks!

> High time to get the pull request out of the door ...

Please ;-)

Ian.
diff mbox

Patch

diff --git a/ui/console.c b/ui/console.c
index 85f46ae..f6ce0ef 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -143,8 +143,6 @@  struct QemuConsole {
     TextCell *cells;
     int text_x[2], text_y[2], cursor_invalidate;
     int echo;
-    bool cursor_visible_phase;
-    QEMUTimer *cursor_timer;
 
     int update_x0;
     int update_y0;
@@ -177,10 +175,14 @@  static DisplayState *display_state;
 static QemuConsole *active_console;
 static QemuConsole *consoles[MAX_CONSOLES];
 static int nb_consoles = 0;
+static bool cursor_visible_phase;
+static QEMUTimer *cursor_timer;
 
 static void text_console_do_init(CharDriverState *chr, DisplayState *ds);
 static void dpy_refresh(DisplayState *s);
 static DisplayState *get_alloc_displaystate(void);
+static void text_console_update_cursor_timer(void);
+static void text_console_update_cursor(void *opaque);
 
 static void gui_update(void *opaque)
 {
@@ -530,7 +532,7 @@  static void console_show_cursor(QemuConsole *s, int show)
     }
     if (y < s->height) {
         c = &s->cells[y1 * s->width + x];
-        if (show && s->cursor_visible_phase) {
+        if (show && cursor_visible_phase) {
             TextAttributes t_attrib = s->t_attrib_default;
             t_attrib.invers = !(t_attrib.invers); /* invert fg and bg */
             vga_putcharxy(s, x, y, c->ch, &t_attrib);
@@ -989,9 +991,6 @@  void console_select(unsigned int index)
     if (s) {
         DisplayState *ds = s->ds;
 
-        if (active_console && active_console->cursor_timer) {
-            timer_del(active_console->cursor_timer);
-        }
         active_console = s;
         if (ds->have_gfx) {
             QLIST_FOREACH(dcl, &ds->listeners, next) {
@@ -1008,10 +1007,7 @@  void console_select(unsigned int index)
         if (ds->have_text) {
             dpy_text_resize(s, s->width, s->height);
         }
-        if (s->cursor_timer) {
-            timer_mod(s->cursor_timer,
-                   qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + CONSOLE_CURSOR_PERIOD / 2);
-        }
+        text_console_update_cursor(NULL);
     }
 }
 
@@ -1314,6 +1310,7 @@  void register_displaychangelistener(DisplayChangeListener *dcl)
             dcl->ops->dpy_gfx_switch(dcl, dummy);
         }
     }
+    text_console_update_cursor(NULL);
 }
 
 void update_displaychangelistener(DisplayChangeListener *dcl,
@@ -1537,6 +1534,8 @@  static DisplayState *get_alloc_displaystate(void)
 {
     if (!display_state) {
         display_state = g_new0(DisplayState, 1);
+        cursor_timer = timer_new_ms(QEMU_CLOCK_REALTIME,
+                                    text_console_update_cursor, NULL);
     }
     return display_state;
 }
@@ -1696,14 +1695,32 @@  static void text_console_set_echo(CharDriverState *chr, bool echo)
     s->echo = echo;
 }
 
+static void text_console_update_cursor_timer(void)
+{
+    timer_mod(cursor_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME)
+              + CONSOLE_CURSOR_PERIOD / 2);
+}
+
 static void text_console_update_cursor(void *opaque)
 {
-    QemuConsole *s = opaque;
+    QemuConsole *s;
+    int i, count = 0;
+
+    cursor_visible_phase = !cursor_visible_phase;
 
-    s->cursor_visible_phase = !s->cursor_visible_phase;
-    graphic_hw_invalidate(s);
-    timer_mod(s->cursor_timer,
-                   qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + CONSOLE_CURSOR_PERIOD / 2);
+    for (i = 0; i < nb_consoles; i++) {
+        s = consoles[i];
+        if (qemu_console_is_graphic(s) ||
+            !qemu_console_is_visible(s)) {
+            continue;
+        }
+        count++;
+        graphic_hw_invalidate(s);
+    }
+
+    if (count) {
+        text_console_update_cursor_timer();
+    }
 }
 
 static const GraphicHwOps text_console_ops = {
@@ -1739,9 +1756,6 @@  static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
         s->surface = qemu_create_displaysurface(g_width, g_height);
     }
 
-    s->cursor_timer =
-        timer_new_ms(QEMU_CLOCK_REALTIME, text_console_update_cursor, s);
-
     s->hw_ops = &text_console_ops;
     s->hw = s;