[vte/vte-0-34] Part of Bug 646098 - vte uses too many file descriptors



commit 5ad51c95557f4e953af066b551bbd9b295c88df4
Author: Behdad Esfahbod <behdad behdad org>
Date:   Sun Sep 29 16:25:48 2013 -0400

    Part of Bug 646098 - vte uses too many file descriptors
    
    Patch from Egmont Koblinger, from comment 13.

 src/ring.c |   37 ++++++++++++++++++++++++++++++-------
 src/ring.h |    4 +++-
 src/vte.c  |    3 +++
 3 files changed, 36 insertions(+), 8 deletions(-)
---
diff --git a/src/ring.c b/src/ring.c
index 3d485e7..6183724 100644
--- a/src/ring.c
+++ b/src/ring.c
@@ -73,6 +73,8 @@ _vte_ring_init (VteRing *ring, gulong max_rows)
        _vte_row_data_init (&ring->cached_row);
        ring->cached_row_num = (gulong) -1;
 
+       ring->visible_rows_hint = 0;
+
        _vte_ring_validate(ring);
 }
 
@@ -96,8 +98,8 @@ _vte_ring_fini (VteRing *ring)
 }
 
 typedef struct _VteRowRecord {
-       gsize text_start_offset;  // offset where text of this row begins
-       gsize attr_start_offset;  // offset of the first character's attributes
+       gsize text_start_offset;  /* offset where text of this row begins */
+       gsize attr_start_offset;  /* offset of the first character's attributes */
 } VteRowRecord;
 
 static gboolean
@@ -353,6 +355,9 @@ _vte_ring_freeze_one_row (VteRing *ring)
 {
        VteRowData *row;
 
+       /* We should never even try to freeze if writable is less than a screenful from the end */
+       g_assert(ring->writable + ring->visible_rows_hint < ring->end);
+
        if (G_UNLIKELY (ring->writable == ring->start))
                _vte_ring_reset_streams (ring, ring->writable);
 
@@ -398,8 +403,10 @@ _vte_ring_discard_one_row (VteRing *ring)
 static void
 _vte_ring_maybe_freeze_one_row (VteRing *ring)
 {
-       if (G_LIKELY (ring->writable + ring->mask == ring->end))
+       if (G_LIKELY (ring->mask >= ring->visible_rows_hint && ring->writable + ring->mask + 1 == ring->end))
                _vte_ring_freeze_one_row (ring);
+       else
+               _vte_ring_ensure_writable_room (ring);
 }
 
 static void
@@ -415,15 +422,18 @@ _vte_ring_ensure_writable_room (VteRing *ring)
        gulong new_mask, old_mask, i, end;
        VteRowData *old_array, *new_array;;
 
-       if (G_LIKELY (ring->writable + ring->mask > ring->end))
+       if (G_LIKELY (ring->mask >= ring->visible_rows_hint && ring->writable + ring->mask + 1 > ring->end))
                return;
 
-       _vte_debug_print(VTE_DEBUG_RING, "Enlarging writable array.\n");
-
        old_mask = ring->mask;
        old_array = ring->array;
 
-       ring->mask = (ring->mask << 1) + 1;
+       do {
+               ring->mask = (ring->mask << 1) + 1;
+       } while (ring->mask < ring->visible_rows_hint || ring->writable + ring->mask + 1 <= ring->end);
+
+       _vte_debug_print(VTE_DEBUG_RING, "Enlarging writable array from %lu to %lu\n", old_mask, ring->mask);
+
        ring->array = g_malloc0 (sizeof (ring->array[0]) * (ring->mask + 1));
 
        new_mask = ring->mask;
@@ -586,6 +596,19 @@ _vte_ring_append (VteRing * ring)
 }
 
 
+/**
+ * _vte_ring_set_visible_rows_hint:
+ * @ring: a #VteRing
+ *
+ * Set the number of visible rows, a hint only for better performance.
+ */
+void
+_vte_ring_set_visible_rows_hint (VteRing *ring, gulong rows)
+{
+       ring->visible_rows_hint = rows;
+}
+
+
 static gboolean
 _vte_ring_write_row (VteRing *ring,
                     GOutputStream *stream,
diff --git a/src/ring.h b/src/ring.h
index d39b690..d4cab96 100644
--- a/src/ring.h
+++ b/src/ring.h
@@ -33,7 +33,7 @@ G_BEGIN_DECLS
 
 
 typedef struct _VteCellAttrChange {
-       gsize text_end_offset;  // offset of first character no longer using this attr
+       gsize text_end_offset;  /* offset of first character no longer using this attr */
        VteIntCellAttr attr;
 } VteCellAttrChange;
 
@@ -62,6 +62,7 @@ struct _VteRing {
        VteRowData cached_row;
        gulong cached_row_num;
 
+       gulong visible_rows_hint;  /* to keep at least a screenful of lines in memory, bug 646098 comment 12 
*/
 };
 
 #define _vte_ring_contains(__ring, __position) \
@@ -81,6 +82,7 @@ void _vte_ring_shrink (VteRing *ring, gulong max_len);
 VteRowData *_vte_ring_insert (VteRing *ring, gulong position);
 VteRowData *_vte_ring_append (VteRing *ring);
 void _vte_ring_remove (VteRing *ring, gulong position);
+void _vte_ring_set_visible_rows_hint (VteRing *ring, gulong rows);
 gboolean _vte_ring_write_contents (VteRing *ring,
                                   GOutputStream *stream,
                                   VteTerminalWriteFlags flags,
diff --git a/src/vte.c b/src/vte.c
index fa1c417..830a372 100644
--- a/src/vte.c
+++ b/src/vte.c
@@ -8126,6 +8126,9 @@ vte_terminal_set_size(VteTerminal *terminal, glong columns, glong rows)
                terminal->column_count = columns;
        }
        if (old_rows != terminal->row_count || old_columns != terminal->column_count) {
+               _vte_ring_set_visible_rows_hint(terminal->pvt->normal_screen.row_data, terminal->row_count);
+               _vte_ring_set_visible_rows_hint(terminal->pvt->alternate_screen.row_data, 
terminal->row_count);
+
                /* Always resize normal screen, even if alternate is visible: bug 415277 */
                vte_terminal_screen_set_size(terminal, &terminal->pvt->normal_screen, old_columns, old_rows);
                if (terminal->pvt->screen == &terminal->pvt->alternate_screen)


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