import threading class FlowControl: "A class meant to control the access to any given dataset; a complex lock." def __init__(self): self.modifier_queue = [] self.accessor_queue = [] self.modifying = False # Whether something is modifying now self.accessing = 0 # How many are accessing. (refcount) self.checking = False # Additional threadsafeness def queueModifier(self, mod): "Add 'mod' to the modifier queue, and try to run it." self.modifier_queue.append(mod) self.checkQueues() def queueAccessor(self, acc): "Add 'acc' to the accessor queue, and try to run it." self.accessor_queue.append(acc) self.checkQueues() def checkQueues(self): "[Internal] Checks the queues and runs threads where they can be run." # This is where all the logic is, if you can't tell. # You'll notice that it prioritizes accessors over modifiers. # May want to switch that around, or even modify the class # to accept high and low priority calls. (Adding a new FOAF # doesn't take long, but crunching takes a while, etc) if self.modifying or self.checking: return self.checking = True try: while len(self.accessor_queue) > 0: self.accessing += 1 func = self.accessor_queue.pop() def wrapit(): func() self.accessing -= 1 self.checkQueues() t = threading.Thread(target=wrapit) print t t.start() if self.accessing == 0 and len(self.modifier_queue) > 0: self.modifying = True func = self.modifier_queue.pop(0) def wrapit(): func() self.modifying = False self.checkQueues() t = threading.Thread(target=wrapit) print t t.start() self.checking = False except: self.checking = False