~nchohan/appscale/zk3.3.4

« back to all changes in this revision

Viewing changes to AppServer/google/appengine/_internal/django/utils/synch.py

  • Committer: Chris Bunch
  • Date: 2012-02-17 08:19:21 UTC
  • mfrom: (787.2.3 appscale-raj-merge)
  • Revision ID: cgb@cs.ucsb.edu-20120217081921-pakidyksaenlpzur
merged with main branch, gaining rabbitmq and upgrades for hbase, cassandra, and hypertable, as well as upgrading to gae 1.6.1 for python and go

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""
 
2
Synchronization primitives:
 
3
 
 
4
    - reader-writer lock (preference to writers)
 
5
 
 
6
(Contributed to Django by eugene@lazutkin.com)
 
7
"""
 
8
 
 
9
try:
 
10
    import threading
 
11
except ImportError:
 
12
    import dummy_threading as threading
 
13
 
 
14
class RWLock:
 
15
    """
 
16
    Classic implementation of reader-writer lock with preference to writers.
 
17
 
 
18
    Readers can access a resource simultaneously.
 
19
    Writers get an exclusive access.
 
20
 
 
21
    API is self-descriptive:
 
22
        reader_enters()
 
23
        reader_leaves()
 
24
        writer_enters()
 
25
        writer_leaves()
 
26
    """
 
27
    def __init__(self):
 
28
        self.mutex     = threading.RLock()
 
29
        self.can_read  = threading.Semaphore(0)
 
30
        self.can_write = threading.Semaphore(0)
 
31
        self.active_readers  = 0
 
32
        self.active_writers  = 0
 
33
        self.waiting_readers = 0
 
34
        self.waiting_writers = 0
 
35
 
 
36
    def reader_enters(self):
 
37
        self.mutex.acquire()
 
38
        try:
 
39
            if self.active_writers == 0 and self.waiting_writers == 0:
 
40
                self.active_readers += 1
 
41
                self.can_read.release()
 
42
            else:
 
43
                self.waiting_readers += 1
 
44
        finally:
 
45
            self.mutex.release()
 
46
        self.can_read.acquire()
 
47
 
 
48
    def reader_leaves(self):
 
49
        self.mutex.acquire()
 
50
        try:
 
51
            self.active_readers -= 1
 
52
            if self.active_readers == 0 and self.waiting_writers != 0:
 
53
                self.active_writers  += 1
 
54
                self.waiting_writers -= 1
 
55
                self.can_write.release()
 
56
        finally:
 
57
            self.mutex.release()
 
58
 
 
59
    def writer_enters(self):
 
60
        self.mutex.acquire()
 
61
        try:
 
62
            if self.active_writers == 0 and self.waiting_writers == 0 and self.active_readers == 0:
 
63
                self.active_writers += 1
 
64
                self.can_write.release()
 
65
            else:
 
66
                self.waiting_writers += 1
 
67
        finally:
 
68
            self.mutex.release()
 
69
        self.can_write.acquire()
 
70
 
 
71
    def writer_leaves(self):
 
72
        self.mutex.acquire()
 
73
        try:
 
74
            self.active_writers -= 1
 
75
            if self.waiting_writers != 0:
 
76
                self.active_writers  += 1
 
77
                self.waiting_writers -= 1
 
78
                self.can_write.release()
 
79
            elif self.waiting_readers != 0:
 
80
                t = self.waiting_readers
 
81
                self.waiting_readers = 0
 
82
                self.active_readers += t
 
83
                while t > 0:
 
84
                    self.can_read.release()
 
85
                    t -= 1
 
86
        finally:
 
87
            self.mutex.release()