nodes: 0, module; 1, function_definition; 2, function_name:local_services; 3, parameters; 4, block; 5, identifier:self; 6, expression_statement; 7, if_statement; 8, try_statement; 9, comment:"""Get a list of id, name pairs for all of the known synced services.
  
          This method is safe to call outside of the background event loop
          without any race condition.  Internally it uses a thread-safe mutex to
          protect the local copies of supervisor data and ensure that it cannot
          change while this method is iterating over it.
  
          Returns:
              list (id, name): A list of tuples with id and service name sorted by id
                  from low to high
          """; 10, not_operator; 11, block; 12, block; 13, finally_clause; 14, call; 15, expression_statement; 16, return_statement; 17, block; 18, attribute; 19, argument_list; 20, call; 21, call; 22, if_statement; 23, attribute; 24, identifier:inside_loop; 25, attribute; 26, argument_list; 27, identifier:sorted; 28, argument_list; 29, not_operator; 30, block; 31, identifier:self; 32, identifier:_loop; 33, attribute; 34, identifier:acquire; 35, list_comprehension; 36, keyword_argument; 37, call; 38, expression_statement; 39, identifier:self; 40, identifier:_state_lock; 41, tuple; 42, for_in_clause; 43, identifier:key; 44, lambda; 45, attribute; 46, argument_list; 47, call; 48, identifier:index; 49, identifier:name; 50, pattern_list; 51, call; 52, lambda_parameters; 53, subscript; 54, attribute; 55, identifier:inside_loop; 56, attribute; 57, argument_list; 58, identifier:index; 59, identifier:name; 60, attribute; 61, argument_list; 62, identifier:element; 63, identifier:element; 64, integer:0; 65, identifier:self; 66, identifier:_loop; 67, attribute; 68, identifier:release; 69, attribute; 70, identifier:items; 71, identifier:self; 72, identifier:_state_lock; 73, identifier:self; 74, identifier:_name_map
code: def local_services(self):
          """Get a list of id, name pairs for all of the known synced services.
  
          This method is safe to call outside of the background event loop
          without any race condition.  Internally it uses a thread-safe mutex to
          protect the local copies of supervisor data and ensure that it cannot
          change while this method is iterating over it.
  
          Returns:
              list (id, name): A list of tuples with id and service name sorted by id
                  from low to high
          """
  
          if not self._loop.inside_loop():
              self._state_lock.acquire()
  
          try:
              return sorted([(index, name) for index, name in self._name_map.items()], key=lambda element: element[0])
          finally:
              if not self._loop.inside_loop():
                  self._state_lock.release()