diff --git a/gdb/tui/tui-data.c b/gdb/tui/tui-data.c
index c308237d187..fe1f73f02e8 100644
--- a/gdb/tui/tui-data.c
+++ b/gdb/tui/tui-data.c
@@ -36,7 +36,6 @@ struct tui_win_info *tui_win_list[MAX_MAJOR_WINDOWS];
 ** Private data
 ****************************/
 static int term_height, term_width;
-static std::vector<tui_source_window_base *> source_windows;
 static struct tui_win_info *win_with_focus = NULL;
 
 static int win_resized = FALSE;
@@ -88,26 +87,6 @@ tui_set_win_with_focus (struct tui_win_info *win_info)
 }
 
 
-/* Accessor for the current source window.  Usually there is only one
-   source window (either source or disassembly), but both can be
-   displayed at the same time.  */
-std::vector<tui_source_window_base *> &
-tui_source_windows ()
-{
-  return source_windows;
-}
-
-
-/* Clear the list of source windows.  Usually there is only one source
-   window (either source or disassembly), but both can be displayed at
-   the same time.  */
-void
-tui_clear_source_windows ()
-{
-  source_windows.clear ();
-}
-
-
 /* Clear the pertinent detail in the source windows.  */
 void
 tui_clear_source_windows_detail ()
@@ -117,16 +96,6 @@ tui_clear_source_windows_detail ()
 }
 
 
-/* Add a window to the list of source windows.  Usually there is only
-   one source window (either source or disassembly), but both can be
-   displayed at the same time.  */
-void
-tui_add_to_source_windows (struct tui_source_window_base *win_info)
-{
-  if (source_windows.size () < 2)
-    source_windows.push_back (win_info);
-}
-
 /* Accessor for the term_height.  */
 int
 tui_term_height (void)
diff --git a/gdb/tui/tui-data.h b/gdb/tui/tui-data.h
index 329fafc2552..338867917ef 100644
--- a/gdb/tui/tui-data.h
+++ b/gdb/tui/tui-data.h
@@ -324,10 +324,7 @@ extern void tui_set_term_height_to (int);
 extern int tui_term_width (void);
 extern void tui_set_term_width_to (int);
 extern struct tui_locator_window *tui_locator_win_info_ptr (void);
-extern std::vector<tui_source_window_base *> &tui_source_windows ();
-extern void tui_clear_source_windows (void);
 extern void tui_clear_source_windows_detail (void);
-extern void tui_add_to_source_windows (struct tui_source_window_base *);
 extern struct tui_win_info *tui_win_with_focus (void);
 extern void tui_set_win_with_focus (struct tui_win_info *);
 extern int tui_win_resized (void);
diff --git a/gdb/tui/tui-layout.c b/gdb/tui/tui-layout.c
index c7facc98343..4ea604a1017 100644
--- a/gdb/tui/tui-layout.c
+++ b/gdb/tui/tui-layout.c
@@ -76,10 +76,6 @@ show_layout (enum tui_layout_type layout)
 
   if (layout != cur_layout)
     {
-      /* Since the new layout may cause changes in window size, we
-         should free the content and reallocate on next display of
-         source/asm.  */
-      tui_clear_source_windows ();
       /* First make the current layout be invisible.  */
       tui_make_all_invisible ();
       tui_locator_win_info_ptr ()->make_visible (false);
@@ -93,16 +89,12 @@ show_layout (enum tui_layout_type layout)
 	  /* Now show the new layout.  */
 	case SRC_COMMAND:
 	  show_source_command ();
-	  tui_add_to_source_windows (TUI_SRC_WIN);
 	  break;
 	case DISASSEM_COMMAND:
 	  show_disasm_command ();
-	  tui_add_to_source_windows (TUI_DISASM_WIN);
 	  break;
 	case SRC_DISASSEM_COMMAND:
 	  show_source_disasm_command ();
-	  tui_add_to_source_windows (TUI_SRC_WIN);
-	  tui_add_to_source_windows (TUI_DISASM_WIN);
 	  break;
 	default:
 	  break;
@@ -595,7 +587,6 @@ show_data (enum tui_layout_type new_layout)
   base->m_has_locator = true;
   locator->make_visible (true);
   tui_show_locator_content ();
-  tui_add_to_source_windows (base);
   TUI_CMD_WIN->make_visible (true);
   current_layout = new_layout;
 }
diff --git a/gdb/tui/tui-win.c b/gdb/tui/tui-win.c
index 7210f6c4119..aa07dfc8225 100644
--- a/gdb/tui/tui-win.c
+++ b/gdb/tui/tui-win.c
@@ -571,7 +571,7 @@ tui_resize_all (void)
        {
 	case SRC_COMMAND:
 	case DISASSEM_COMMAND:
-	  src_win = tui_source_windows ()[0];
+	  src_win = *(tui_source_windows ().begin ());
 	  first_win = src_win;
 	  first_win->width += width_diff;
 	  locator->width += width_diff;
@@ -610,7 +610,7 @@ tui_resize_all (void)
 	    {
 	      first_win = TUI_DATA_WIN;
 	      first_win->width += width_diff;
-	      src_win = tui_source_windows ()[0];
+	      src_win = *(tui_source_windows ().begin ());
 	      second_win = src_win;
 	      second_win->width += width_diff;
 	    }
@@ -1046,7 +1046,7 @@ tui_adjust_win_heights (struct tui_win_info *primary_win_info,
 	      primary_win_info->make_invisible_and_set_new_height (new_height);
 	      if (primary_win_info->type == CMD_WIN)
 		{
-		  win_info = tui_source_windows ()[0];
+		  win_info = *(tui_source_windows ().begin ());
 		  src_win_info = win_info;
 		}
 	      else
@@ -1084,7 +1084,7 @@ tui_adjust_win_heights (struct tui_win_info *primary_win_info,
 		{
 		  src1 = nullptr;
 		  first_win = TUI_DATA_WIN;
-		  second_win = tui_source_windows ()[0];
+		  second_win = *(tui_source_windows ().begin ());
 		}
 	      if (primary_win_info == TUI_CMD_WIN)
 		{ /* Split the change in height accross the 1st & 2nd
@@ -1238,7 +1238,7 @@ new_height_ok (struct tui_win_info *primary_win_info,
 	      struct tui_win_info *win_info;
 
 	      if (primary_win_info == TUI_CMD_WIN)
-		win_info = tui_source_windows ()[0];
+		win_info = *(tui_source_windows ().begin ());
 	      else
 		win_info = TUI_CMD_WIN;
 	      ok = ((new_height +
@@ -1259,7 +1259,7 @@ new_height_ok (struct tui_win_info *primary_win_info,
 	  else
 	    {
 	      first_win = TUI_DATA_WIN;
-	      second_win = tui_source_windows ()[0];
+	      second_win = *(tui_source_windows ().begin ());
 	    }
 	  /* We could simply add all the heights to obtain the same
 	     result but below is more explicit since we subtract 1 for
@@ -1385,7 +1385,7 @@ parse_scrolling_args (const char *arg,
 	  if (!(*win_to_scroll)->is_visible)
 	    error (_("Window is not visible"));
 	  else if (*win_to_scroll == TUI_CMD_WIN)
-	    *win_to_scroll = tui_source_windows ()[0];
+	    *win_to_scroll = *(tui_source_windows ().begin ());
 	}
     }
 }
diff --git a/gdb/tui/tui-winsource.c b/gdb/tui/tui-winsource.c
index f62c79dc32a..613213fab5f 100644
--- a/gdb/tui/tui-winsource.c
+++ b/gdb/tui/tui-winsource.c
@@ -44,7 +44,8 @@
 void
 tui_display_main ()
 {
-  if (!tui_source_windows ().empty ())
+  auto adapter = tui_source_windows ();
+  if (adapter.begin () != adapter.end ())
     {
       struct gdbarch *gdbarch;
       CORE_ADDR addr;
diff --git a/gdb/tui/tui-winsource.h b/gdb/tui/tui-winsource.h
index 6627e70bc98..a3208060080 100644
--- a/gdb/tui/tui-winsource.h
+++ b/gdb/tui/tui-winsource.h
@@ -154,6 +154,76 @@ public:
   std::vector<tui_source_element> content;
 };
 
+
+/* A wrapper for a TUI window iterator that only iterates over source
+   windows.  */
+
+struct tui_source_window_iterator
+{
+public:
+
+  typedef tui_source_window_iterator self_type;
+  typedef struct tui_source_window_base *value_type;
+  typedef struct tui_source_window_base *&reference;
+  typedef struct tui_source_window_base **pointer;
+  typedef std::forward_iterator_tag iterator_category;
+  typedef int difference_type;
+
+  explicit tui_source_window_iterator (bool dummy)
+    : m_iter (SRC_WIN)
+  {
+    advance ();
+  }
+
+  tui_source_window_iterator ()
+    : m_iter (tui_win_type (DISASSEM_WIN + 1))
+  {
+  }
+
+  bool operator!= (const self_type &other) const
+  {
+    return m_iter != other.m_iter;
+  }
+
+  value_type operator* () const
+  {
+    return (value_type) *m_iter;
+  }
+
+  self_type &operator++ ()
+  {
+    ++m_iter;
+    advance ();
+    return *this;
+  }
+
+private:
+
+  void advance ()
+  {
+    tui_window_iterator end;
+    while (m_iter != end && *m_iter == nullptr)
+      ++m_iter;
+  }
+
+  tui_window_iterator m_iter;
+};
+
+/* A range adapter for source windows.  */
+
+struct tui_source_windows
+{
+  tui_source_window_iterator begin () const
+  {
+    return tui_source_window_iterator (true);
+  }
+
+  tui_source_window_iterator end () const
+  {
+    return tui_source_window_iterator ();
+  }
+};
+
 /* Update the execution windows to show the active breakpoints.  This
    is called whenever a breakpoint is inserted, removed or has its
    state changed.  Normally BEING_DELETED is nullptr; if not nullptr,
