Package concurrent_tree_crawler :: Module rw_lock_tree_accessor
[hide private]
[frames] | no frames]

Source Code for Module concurrent_tree_crawler.rw_lock_tree_accessor

 1  from concurrent_tree_crawler.common.threads.rw_lock import RWLock 
 2  from concurrent_tree_crawler.tree_accessor import TreeAccessor 
 3  from concurrent_tree_crawler.abstract_node import NodeState 
 4  from concurrent_tree_crawler.abstract_tree_accessor import NodeAction 
 5   
6 -class RWLockTreeAccessor(TreeAccessor):
7 """ 8 A version of the L{TreeAccessor} where sensitive methods are protected by 9 readers-writers lock. 10 """ 11
12 - def __init__(self, sentinel):
13 TreeAccessor.__init__(self, sentinel) 14 self.__lock = RWLock()
15
16 - def get_lock(self):
17 return self.__lock
18
19 - def update_and_get_child(self, node, possible_children_names):
20 while True: 21 node.get_children_cond().acquire() 22 try: 23 child_info = self.__update_with_potential_tree_change( 24 node, possible_children_names) 25 if child_info is None: 26 return None 27 (child, state) = child_info 28 if state == NodeState.OPEN: 29 return (child, NodeAction.TO_PROCESS) 30 elif state == NodeState.VISITED: 31 return (child, NodeAction.TO_VISIT) 32 elif state == NodeState.PROCESSING: 33 node.get_children_cond().wait() 34 else: 35 assert False, "Unknown node state: {}".format(state) 36 finally: 37 node.get_children_cond().release()
38
39 - def __update_with_potential_tree_change(self, 40 node, possible_children_names):
41 ## We have to acquire this lock if we're going to make some 42 ## changes in the tree. This will prevent the `TreeSaverThread` 43 ## from accessing the tree while it is modified. 44 self.__lock.reader_acquire() 45 try: 46 child = node.update_and_get_child(possible_children_names) 47 if child is None: ## No accessible children are available 48 return None 49 state = child.get_state() 50 if state == NodeState.OPEN: 51 child.set_state(NodeState.PROCESSING) 52 return (child, state) 53 finally: 54 self.__lock.reader_release()
55
56 - def set_node_type(self, node, is_leaf):
57 self.__lock.reader_acquire() 58 try: 59 TreeAccessor.set_node_type(self, node, is_leaf) 60 finally: 61 self.__lock.reader_release()
62
63 - def set_error(self, node):
64 self.__lock.reader_acquire() 65 try: 66 TreeAccessor.set_error(self, node) 67 finally: 68 self.__lock.reader_release()
69