[tor-commits] [nyx/master] Drop config panel lock

atagar at torproject.org atagar at torproject.org
Mon Jan 4 17:43:05 UTC 2016


commit 992d531064c20809bdb1ab07b548eabc73aca3b1
Author: Damian Johnson <atagar at torproject.org>
Date:   Wed Nov 11 10:14:17 2015 -0800

    Drop config panel lock
    
    This is definitely a panel that doesn't need a lock. There might be some edge
    cases this is risky for at present but I'll be paying special attention to the
    concurrency issues as I rewrite it.
---
 nyx/config_panel.py |  190 ++++++++++++++++++++++++---------------------------
 1 file changed, 90 insertions(+), 100 deletions(-)

diff --git a/nyx/config_panel.py b/nyx/config_panel.py
index 99d1a3d..36688a9 100644
--- a/nyx/config_panel.py
+++ b/nyx/config_panel.py
@@ -4,7 +4,6 @@ and the resulting configuration files saved.
 """
 
 import curses
-import threading
 
 import nyx.controller
 import nyx.popups
@@ -168,7 +167,6 @@ class ConfigPanel(panel.Panel):
     self._conf_contents = []
     self._conf_important_contents = []
     self._scroller = ui_tools.Scroller(True)
-    self._vals_lock = threading.RLock()
     self._sort_order = CONFIG['features.config.order']
     self._show_all = False  # show all options, or just the 'important' ones
 
@@ -244,59 +242,58 @@ class ConfigPanel(panel.Panel):
       self._conf_important_contents = sorted(self._conf_important_contents, key = lambda entry: [entry.sort_value(field) for field in self._sort_order])
 
   def handle_key(self, key):
-    with self._vals_lock:
-      if key.is_scroll():
-        page_height = self.get_preferred_size()[0] - DETAILS_HEIGHT - 2
-        is_changed = self._scroller.handle_key(key, self._get_config_options(), page_height)
-
-        if is_changed:
-          self.redraw(True)
-      elif key.is_selection() and self._get_config_options():
-        # Prompts the user to edit the selected configuration value. The
-        # interface is locked to prevent updates between setting the value
-        # and showing any errors.
-
-        with panel.CURSES_LOCK:
-          selection = self.get_selection()
-          config_option = selection.option()
-
-          initial_value = '' if not selection.is_set() else selection.value()
-          prompt_msg = '%s Value (esc to cancel): ' % config_option
-          new_value = nyx.popups.input_prompt(prompt_msg, initial_value)
-
-          if new_value is not None and new_value != initial_value:
-            try:
-              if selection.value_type() == 'Boolean':
-                # if the value's a boolean then allow for 'true' and 'false' inputs
-
-                if new_value.lower() == 'true':
-                  new_value = '1'
-                elif new_value.lower() == 'false':
-                  new_value = '0'
-              elif selection.value_type() == 'LineList':
-                # set_option accepts list inputs when there's multiple values
-                new_value = new_value.split(',')
-
-              tor_controller().set_conf(config_option, new_value)
-
-              # forces the label to be remade with the new value
-
-              selection.label_cache = None
-
-              self.redraw(True)
-            except Exception as exc:
-              nyx.popups.show_msg('%s (press any key)' % exc)
-      elif key.match('a'):
-        self._show_all = not self._show_all
+    if key.is_scroll():
+      page_height = self.get_preferred_size()[0] - DETAILS_HEIGHT - 2
+      is_changed = self._scroller.handle_key(key, self._get_config_options(), page_height)
+
+      if is_changed:
         self.redraw(True)
-      elif key.match('s'):
-        self.show_sort_dialog()
-      elif key.match('v'):
-        self.show_write_dialog()
-      else:
-        return False
+    elif key.is_selection() and self._get_config_options():
+      # Prompts the user to edit the selected configuration value. The
+      # interface is locked to prevent updates between setting the value
+      # and showing any errors.
+
+      with panel.CURSES_LOCK:
+        selection = self.get_selection()
+        config_option = selection.option()
+
+        initial_value = '' if not selection.is_set() else selection.value()
+        prompt_msg = '%s Value (esc to cancel): ' % config_option
+        new_value = nyx.popups.input_prompt(prompt_msg, initial_value)
+
+        if new_value is not None and new_value != initial_value:
+          try:
+            if selection.value_type() == 'Boolean':
+              # if the value's a boolean then allow for 'true' and 'false' inputs
+
+              if new_value.lower() == 'true':
+                new_value = '1'
+              elif new_value.lower() == 'false':
+                new_value = '0'
+            elif selection.value_type() == 'LineList':
+              # set_option accepts list inputs when there's multiple values
+              new_value = new_value.split(',')
+
+            tor_controller().set_conf(config_option, new_value)
+
+            # forces the label to be remade with the new value
+
+            selection.label_cache = None
+
+            self.redraw(True)
+          except Exception as exc:
+            nyx.popups.show_msg('%s (press any key)' % exc)
+    elif key.match('a'):
+      self._show_all = not self._show_all
+      self.redraw(True)
+    elif key.match('s'):
+      self.show_sort_dialog()
+    elif key.match('v'):
+      self.show_write_dialog()
+    else:
+      return False
 
-      return True
+    return True
 
   def show_write_dialog(self):
     """
@@ -442,66 +439,61 @@ class ConfigPanel(panel.Panel):
     ]
 
   def draw(self, width, height):
-    with self._vals_lock:
-      # panel with details for the current selection
+    # Shrink detail panel if there isn't sufficient room for the whole
+    # thing. The extra line is for the bottom border.
 
-      is_scrollbar_visible = False
+    scroll_location = self._scroller.get_scroll_location(self._get_config_options(), height - DETAILS_HEIGHT - 2)
+    cursor_selection = self.get_selection()
+    is_scrollbar_visible = len(self._get_config_options()) > height - DETAILS_HEIGHT - 2
 
-      # Shrink detail panel if there isn't sufficient room for the whole
-      # thing. The extra line is for the bottom border.
+    if cursor_selection is not None:
+      self._draw_selection_panel(cursor_selection, width, DETAILS_HEIGHT + 1, is_scrollbar_visible)
 
-      scroll_location = self._scroller.get_scroll_location(self._get_config_options(), height - DETAILS_HEIGHT - 2)
-      cursor_selection = self.get_selection()
-      is_scrollbar_visible = len(self._get_config_options()) > height - DETAILS_HEIGHT - 2
+    # draws the top label
 
-      if cursor_selection is not None:
-        self._draw_selection_panel(cursor_selection, width, DETAILS_HEIGHT + 1, is_scrollbar_visible)
+    if self.is_title_visible():
+      hidden_msg = "press 'a' to hide most options" if self._show_all else "press 'a' to show all options"
+      title_label = 'Tor Configuration (%s):' % hidden_msg
+      self.addstr(0, 0, title_label, curses.A_STANDOUT)
 
-      # draws the top label
+    # draws left-hand scroll bar if content's longer than the height
 
-      if self.is_title_visible():
-        hidden_msg = "press 'a' to hide most options" if self._show_all else "press 'a' to show all options"
-        title_label = 'Tor Configuration (%s):' % hidden_msg
-        self.addstr(0, 0, title_label, curses.A_STANDOUT)
+    scroll_offset = 1
 
-      # draws left-hand scroll bar if content's longer than the height
-
-      scroll_offset = 1
-
-      if is_scrollbar_visible:
-        scroll_offset = 3
-        self.add_scroll_bar(scroll_location, scroll_location + height - DETAILS_HEIGHT - 2, len(self._get_config_options()), DETAILS_HEIGHT + 2)
+    if is_scrollbar_visible:
+      scroll_offset = 3
+      self.add_scroll_bar(scroll_location, scroll_location + height - DETAILS_HEIGHT - 2, len(self._get_config_options()), DETAILS_HEIGHT + 2)
 
-      value_width = VALUE_WIDTH
-      description_width = max(0, width - scroll_offset - OPTION_WIDTH - value_width - 2)
+    value_width = VALUE_WIDTH
+    description_width = max(0, width - scroll_offset - OPTION_WIDTH - value_width - 2)
 
-      # if the description column is overly long then use its space for the
-      # value instead
+    # if the description column is overly long then use its space for the
+    # value instead
 
-      if description_width > 80:
-        value_width += description_width - 80
-        description_width = 80
+    if description_width > 80:
+      value_width += description_width - 80
+      description_width = 80
 
-      for line_number in range(scroll_location, len(self._get_config_options())):
-        entry = self._get_config_options()[line_number]
-        draw_line = line_number + DETAILS_HEIGHT + 2 - scroll_location
+    for line_number in range(scroll_location, len(self._get_config_options())):
+      entry = self._get_config_options()[line_number]
+      draw_line = line_number + DETAILS_HEIGHT + 2 - scroll_location
 
-        line_format = [curses.A_BOLD if entry.is_set() else curses.A_NORMAL]
-        line_format += [CONFIG['attr.config.category_color'].get(entry.category(), 'white')]
+      line_format = [curses.A_BOLD if entry.is_set() else curses.A_NORMAL]
+      line_format += [CONFIG['attr.config.category_color'].get(entry.category(), 'white')]
 
-        if entry == cursor_selection:
-          line_format += [curses.A_STANDOUT]
+      if entry == cursor_selection:
+        line_format += [curses.A_STANDOUT]
 
-        option_label = str_tools.crop(entry.option(), OPTION_WIDTH)
-        value_label = str_tools.crop(entry.value(), value_width)
-        summary_label = str_tools.crop(entry.summary(), description_width, None)
-        line_text_layout = '%%-%is %%-%is %%-%is' % (OPTION_WIDTH, value_width, description_width)
-        line_text = line_text_layout % (option_label, value_label, summary_label)
+      option_label = str_tools.crop(entry.option(), OPTION_WIDTH)
+      value_label = str_tools.crop(entry.value(), value_width)
+      summary_label = str_tools.crop(entry.summary(), description_width, None)
+      line_text_layout = '%%-%is %%-%is %%-%is' % (OPTION_WIDTH, value_width, description_width)
+      line_text = line_text_layout % (option_label, value_label, summary_label)
 
-        self.addstr(draw_line, scroll_offset, line_text, *line_format)
+      self.addstr(draw_line, scroll_offset, line_text, *line_format)
 
-        if draw_line >= height:
-          break
+      if draw_line >= height:
+        break
 
   def _get_config_options(self):
     return self._conf_contents if self._show_all else self._conf_important_contents
@@ -548,10 +540,8 @@ class ConfigPanel(panel.Panel):
     description_content = 'Description: %s' % (selection.manual_entry().description if selection.manual_entry() else '')
 
     for i in range(description_height):
-      # checks if we're done writing the description
-
       if not description_content:
-        break
+        break  # done writing the description
 
       # there's a leading indent after the first line
 





More information about the tor-commits mailing list