blob: 1cec4e30af21f609beb7f9fab3c591c8b9b418fe [file] [log] [blame]
Guido van Rossum9022fce1992-08-25 12:30:44 +00001# A multi-producer, multi-consumer queue.
2
Barry Warsaw3d96d521997-11-20 19:56:38 +00003# define this exception to be compatible with Python 1.5's class
4# exceptions, but also when -X option is used.
5try:
6 class Empty(Exception):
7 pass
8except TypeError:
9 # string based exceptions
10 Empty = 'Queue.Empty' # Exception raised by get_nowait()
Guido van Rossum9022fce1992-08-25 12:30:44 +000011
12class Queue:
Barry Warsaw3d96d521997-11-20 19:56:38 +000013 def __init__(self, maxsize):
14 """Initialize a queue object with a given maximum size.
Guido van Rossum9022fce1992-08-25 12:30:44 +000015
Barry Warsaw3d96d521997-11-20 19:56:38 +000016 If maxsize is <= 0, the queue size is infinite.
17 """
18 import thread
19 self._init(maxsize)
20 self.mutex = thread.allocate_lock()
21 self.esema = thread.allocate_lock()
22 self.esema.acquire_lock()
23 self.fsema = thread.allocate_lock()
Guido van Rossum9022fce1992-08-25 12:30:44 +000024
Barry Warsaw3d96d521997-11-20 19:56:38 +000025 def qsize(self):
26 """Returns the approximate size of the queue (not reliable!)."""
27 self.mutex.acquire_lock()
28 n = self._qsize()
29 self.mutex.release_lock()
30 return n
31
32 def empty(self):
33 """Returns 1 if the queue is empty, 0 otherwise (not reliable!)."""
34 self.mutex.acquire_lock()
35 n = self._empty()
36 self.mutex.release_lock()
37 return n
38
39 def full(self):
40 """Returns 1 if the queue is full, 0 otherwise (not reliable!)."""
41 self.mutex.acquire_lock()
42 n = self._full()
43 self.mutex.release_lock()
44 return n
45
46 def put(self, item):
47 """Put an item into the queue."""
48 self.fsema.acquire_lock()
49 self.mutex.acquire_lock()
50 was_empty = self._empty()
51 self._put(item)
52 if was_empty:
53 self.esema.release_lock()
54 if not self._full():
55 self.fsema.release_lock()
56 self.mutex.release_lock()
57
58 def get(self):
59 """Gets and returns an item from the queue.
60 This method blocks if necessary until an item is available.
61 """
62 self.esema.acquire_lock()
63 self.mutex.acquire_lock()
64 was_full = self._full()
65 item = self._get()
66 if was_full:
67 self.fsema.release_lock()
68 if not self._empty():
69 self.esema.release_lock()
70 self.mutex.release_lock()
71 return item
72
73 # Get an item from the queue if one is immediately available,
74 # raise Empty if the queue is empty or temporarily unavailable
75 def get_nowait(self):
76 """Gets and returns an item from the queue.
77 Only gets an item if one is immediately available, Otherwise
78 this raises the Empty exception if the queue is empty or
79 temporarily unavailable.
80 """
81 locked = self.esema.acquire_lock(0)
82 self.mutex.acquire_lock()
83 if self._empty():
84 # The queue is empty -- we can't have esema
85 self.mutex.release_lock()
86 raise Empty
87 if not locked:
88 locked = self.esema.acquire_lock(0)
89 if not locked:
90 # Somebody else has esema
91 # but we have mutex --
92 # go out of their way
Guido van Rossum9022fce1992-08-25 12:30:44 +000093 self.mutex.release_lock()
Barry Warsaw3d96d521997-11-20 19:56:38 +000094 raise Empty
95 was_full = self._full()
96 item = self._get()
97 if was_full:
98 self.fsema.release_lock()
99 if not self._empty():
100 self.esema.release_lock()
101 self.mutex.release_lock()
102 return item
Guido van Rossum9022fce1992-08-25 12:30:44 +0000103
Barry Warsaw3d96d521997-11-20 19:56:38 +0000104 # XXX Need to define put_nowait() as well.
Guido van Rossum9022fce1992-08-25 12:30:44 +0000105
Guido van Rossum9022fce1992-08-25 12:30:44 +0000106
Barry Warsaw3d96d521997-11-20 19:56:38 +0000107 # Override these methods to implement other queue organizations
108 # (e.g. stack or priority queue).
109 # These will only be called with appropriate locks held
Guido van Rossum9022fce1992-08-25 12:30:44 +0000110
Barry Warsaw3d96d521997-11-20 19:56:38 +0000111 # Initialize the queue representation
112 def _init(self, maxsize):
113 self.maxsize = maxsize
114 self.queue = []
Guido van Rossum9022fce1992-08-25 12:30:44 +0000115
Barry Warsaw3d96d521997-11-20 19:56:38 +0000116 def _qsize(self):
117 return len(self.queue)
Guido van Rossum9022fce1992-08-25 12:30:44 +0000118
Barry Warsaw3d96d521997-11-20 19:56:38 +0000119 # Check wheter the queue is empty
120 def _empty(self):
121 return not self.queue
Guido van Rossum9022fce1992-08-25 12:30:44 +0000122
Barry Warsaw3d96d521997-11-20 19:56:38 +0000123 # Check whether the queue is full
124 def _full(self):
125 return self.maxsize > 0 and len(self.queue) == self.maxsize
Guido van Rossum9022fce1992-08-25 12:30:44 +0000126
Barry Warsaw3d96d521997-11-20 19:56:38 +0000127 # Put a new item in the queue
128 def _put(self, item):
129 self.queue.append(item)
Guido van Rossum9022fce1992-08-25 12:30:44 +0000130
Barry Warsaw3d96d521997-11-20 19:56:38 +0000131 # Get an item from the queue
132 def _get(self):
133 item = self.queue[0]
134 del self.queue[0]
135 return item