Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

Changeset 576

Show
Ignore:
Timestamp:
08/29/05 12:38:00
Author:
fumanchu
Message:

Fixed mrow dependency on Python 2.4's threading.local; also made mrow test into a class.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/cherrypy/lib/filter/sessionfilter/mrow.py

    r575 r576  
    1                                                                                                                                                                                                                                                                 
    2 import threading 
    31 
    42# write should lock out everyone 
    53# read should only lock out writing 
    64 
     5import threading 
     6 
     7try: 
     8    from threading import local 
     9except ImportError: 
     10    from cherrypy._cpthreadinglocal import local 
     11 
     12 
    713class MROWLock(object): 
     14     
    815    def __init__(self): 
    9         self.local = threading.local() 
    10         self.writelock = threading.RLock() # this is required so that multiple writers won't mess up writing event 
    11         self.writing = threading.Event() # must wait() for this; it'll tell you when a write is over (like a lock that you dont acquire, you just wiat for) 
    12         self.writing.set() # we are not writing to it right now 
    13         self.readers = [] # list of all reader Events. when clear, they are reading. must wait() for all of these to be sure no one is reading 
    14         self.readerslock = threading.RLock() # lock for readers list so it is not changed while looping 
     16        self.local = local() 
     17        # this is required so that multiple writers won't mess up writing event 
     18        self.writelock = threading.RLock() 
     19        # must wait() for this; it'll tell you when a write is over 
     20        # (like a lock that you dont acquire, you just wait for) 
     21        self.writing = threading.Event() 
     22        # we are not writing to it right now 
     23        self.writing.set() 
     24        # list of all reader Events. when clear, they are reading. 
     25        # must wait() for all of these to be sure no one is reading 
     26        self.readers = [] 
     27        # lock for readers list so it is not changed while looping 
     28        self.readerslock = threading.RLock() 
    1529     
    1630    def lock_read(self): 
     
    1832            self.local.reader = threading.Event() 
    1933            self.local.reader.set() 
    20             self.readerslock.acquire() # lock the list so it won't mess up the loop in lock_write 
     34            # lock the list so it won't mess up the loop in lock_write 
     35            self.readerslock.acquire() 
    2136            self.readers.append(self.local.reader) 
    2237            self.readerslock.release() 
    2338         
    24         # only wait if the writing thread is not the thread same which is requesting a read lock 
     39        # only wait if the writing thread is not the thread same 
     40        # which is requesting a read lock 
    2541        if not hasattr(self.local, 'writing'): 
    26             self.writing.wait() # wait for any writes to finish 
    27  
     42            # wait for any writes to finish 
     43            self.writing.wait() 
     44         
    2845        # tell everyone we are reading 
    2946        self.local.reader.clear() 
     
    3451        if not hasattr(self.local, 'writing'): 
    3552            self.local.writing = True 
    36             self.writing.wait() # wait for any writes to finish (this is a bit redundant with the next line) 
     53            # wait for any writes to finish 
     54            # (this is a bit redundant with the next line) 
     55            self.writing.wait() 
    3756             
    3857        self.writelock.acquire() 
    39         self.writing.clear() # lock out everyone reading from this dict 
     58        # lock out everyone reading from this dict 
     59        self.writing.clear() 
    4060        self.readerslock.acquire() 
    4161        for reader in self.readers: 
     
    4969     
    5070    def unlock_write(self): 
    51         self.writing.set() # wake everyone else up. TODO: what if one thread has the lock, and another calls this method? 
     71        # wake everyone else up. 
     72        # TODO: what if one thread has the lock, and another calls this method? 
     73        self.writing.set() 
    5274        self.writelock.release() 
    5375 
    5476 
    5577class MROWDict(dict): 
     78     
    5679    def __init__(self, auto_lock = False, auto_lock_safe = True, *args, **kwargs): 
    5780        dict.__init__(self, *args, **kwargs) 
    5881        self._locks = {} 
    5982        self._lockslock = threading.RLock() 
    60         self._auto_lock = auto_lock # automatically acquire locks for getitem setitem (BAD IDEA) 
    61         self._auto_lock_safe = auto_lock_safe # when autolocking, lock the whole dict (GOOD IDEA) 
     83        # automatically acquire locks for getitem setitem (BAD IDEA) 
     84        self._auto_lock = auto_lock 
     85        # when autolocking, lock the whole dict (GOOD IDEA) 
     86        self._auto_lock_safe = auto_lock_safe 
    6287     
    6388    def _init_lock(self, key): 
     
    128153        dict.update(self, values) 
    129154 
    130 ''' 
     155 
    131156# test code 
    132157import time, thread 
    133158 
    134 deadthreads = 0 
    135  
    136 def writer_thread(d, l): 
    137     global deadthreads 
    138     for i in range(0, 100): 
    139         l.lock_write() 
    140         hits = d["hits"] 
    141         hits = hits + 1 
    142         time.sleep(.01) 
    143         d["hits"] = hits 
    144         l.unlock_write() 
    145     deadthreads += 1 
    146  
    147 def reader_thread(d, l): 
    148     while True: 
    149         l.lock_read() 
    150         try: 
    151             hits = d["hits"] 
    152             if deadthreads == 3: 
    153                 if d["hits"] != 300: 
    154                     print "omfg error",d["hits"] 
     159class MROWTest(object): 
     160     
     161    def __init__(self): 
     162        self.deadthreads = 0 
     163        self.hitdict = {"hits": 0} 
     164        self.lock = MROWLock() 
     165        for i in xrange(0, 2): 
     166            thread.start_new_thread(self.reader_thread, ()) 
     167        for i in range(0, 3): 
     168            thread.start_new_thread(self.writer_thread, ()) 
     169        self.reader_thread() 
     170     
     171    def writer_thread(self): 
     172        for i in xrange(100): 
     173            self.lock.lock_write() 
     174            hits = self.hitdict["hits"] + 1 
     175            time.sleep(.01) 
     176            self.hitdict["hits"] = hits 
     177            self.lock.unlock_write() 
     178        self.deadthreads += 1 
     179     
     180    def reader_thread(self): 
     181        while True: 
     182            self.lock.lock_read() 
     183            try: 
     184                hits = self.hitdict["hits"] 
     185                if self.deadthreads == 3: 
    155186                    break 
    156                 else: 
    157                     print "its all ok" 
    158                     break 
    159         finally: 
    160             l.unlock_read() 
    161         time.sleep(.01) 
    162  
    163 def main(): 
    164     global deadthreads 
    165     deadthreads = 0 
    166     d = {} 
    167     d["hits"] = 0 
    168     l = MROWLock() 
    169     for i in range(0, 2): 
    170         thread.start_new_thread(reader_thread, (d,l)) 
    171     for i in range(0, 3): 
    172         thread.start_new_thread(writer_thread, (d,l)) 
    173     reader_thread(d, l) 
     187            finally: 
     188                self.lock.unlock_read() 
     189            time.sleep(.01) 
     190         
     191        if hits != 300: 
     192            print "omfg error", hits 
     193        else: 
     194            print "its all ok" 
     195 
    174196 
    175197if __name__ == "__main__": 
    176198    while True: 
    177         main() 
    178 ''' 
     199        MROWTest() 
     200 
     201del time, thread, MROWTest 

Hosted by WebFaction

Log in as guest/cpguest to create tickets