blob: cb04006f11d2dc32cc2ab24744e922a681c7cace [file] [log] [blame]
Guido van Rossum4acc25b2000-02-02 15:10:15 +00001"""A multi-producer, multi-consumer queue."""
Guido van Rossum9022fce1992-08-25 12:30:44 +00002
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):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +00007 pass
Guido van Rossum9e1721f1999-02-08 18:34:01 +00008 class Full(Exception):
9 pass
Barry Warsaw3d96d521997-11-20 19:56:38 +000010except TypeError:
11 # string based exceptions
Guido van Rossum9e1721f1999-02-08 18:34:01 +000012 # exception raised by get(block=0)/get_nowait()
13 Empty = 'Queue.Empty'
14 # exception raised by put(block=0)/put_nowait()
15 Full = 'Queue.Full'
Guido van Rossum9022fce1992-08-25 12:30:44 +000016
17class Queue:
Guido van Rossuma41c6911999-09-09 14:54:28 +000018 def __init__(self, maxsize=0):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000019 """Initialize a queue object with a given maximum size.
Guido van Rossum9022fce1992-08-25 12:30:44 +000020
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000021 If maxsize is <= 0, the queue size is infinite.
22 """
23 import thread
24 self._init(maxsize)
25 self.mutex = thread.allocate_lock()
26 self.esema = thread.allocate_lock()
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000027 self.esema.acquire()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000028 self.fsema = thread.allocate_lock()
Guido van Rossum9022fce1992-08-25 12:30:44 +000029
Barry Warsaw3d96d521997-11-20 19:56:38 +000030 def qsize(self):
Guido van Rossum9e1721f1999-02-08 18:34:01 +000031 """Return the approximate size of the queue (not reliable!)."""
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000032 self.mutex.acquire()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000033 n = self._qsize()
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000034 self.mutex.release()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000035 return n
Barry Warsaw3d96d521997-11-20 19:56:38 +000036
37 def empty(self):
Guido van Rossum9e1721f1999-02-08 18:34:01 +000038 """Return 1 if the queue is empty, 0 otherwise (not reliable!)."""
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000039 self.mutex.acquire()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000040 n = self._empty()
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000041 self.mutex.release()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000042 return n
Barry Warsaw3d96d521997-11-20 19:56:38 +000043
44 def full(self):
Guido van Rossum9e1721f1999-02-08 18:34:01 +000045 """Return 1 if the queue is full, 0 otherwise (not reliable!)."""
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000046 self.mutex.acquire()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000047 n = self._full()
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000048 self.mutex.release()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000049 return n
Barry Warsaw3d96d521997-11-20 19:56:38 +000050
Guido van Rossum9e1721f1999-02-08 18:34:01 +000051 def put(self, item, block=1):
Guido van Rossumc09e6b11998-04-09 14:25:32 +000052 """Put an item into the queue.
53
Guido van Rossum9e1721f1999-02-08 18:34:01 +000054 If optional arg 'block' is 1 (the default), block if
55 necessary until a free slot is available. Otherwise (block
56 is 0), put an item on the queue if a free slot is immediately
57 available, else raise the Full exception.
58 """
59 if block:
60 self.fsema.acquire()
61 elif not self.fsema.acquire(0):
62 raise Full
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000063 self.mutex.acquire()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000064 was_empty = self._empty()
65 self._put(item)
66 if was_empty:
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000067 self.esema.release()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000068 if not self._full():
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000069 self.fsema.release()
70 self.mutex.release()
Barry Warsaw3d96d521997-11-20 19:56:38 +000071
Guido van Rossum9e1721f1999-02-08 18:34:01 +000072 def put_nowait(self, item):
73 """Put an item into the queue without blocking.
Guido van Rossumc09e6b11998-04-09 14:25:32 +000074
Guido van Rossum9e1721f1999-02-08 18:34:01 +000075 Only enqueue the item if a free slot is immediately available.
76 Otherwise raise the Full exception.
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000077 """
Guido van Rossum9e1721f1999-02-08 18:34:01 +000078 return self.put(item, 0)
Barry Warsaw3d96d521997-11-20 19:56:38 +000079
Guido van Rossum9e1721f1999-02-08 18:34:01 +000080 def get(self, block=1):
81 """Remove and return an item from the queue.
Guido van Rossumc09e6b11998-04-09 14:25:32 +000082
Guido van Rossum9e1721f1999-02-08 18:34:01 +000083 If optional arg 'block' is 1 (the default), block if
84 necessary until an item is available. Otherwise (block is 0),
85 return an item if one is immediately available, else raise the
86 Empty exception.
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000087 """
Guido van Rossum9e1721f1999-02-08 18:34:01 +000088 if block:
89 self.esema.acquire()
90 elif not self.esema.acquire(0):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000091 raise Empty
Guido van Rossum9e1721f1999-02-08 18:34:01 +000092 self.mutex.acquire()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000093 was_full = self._full()
94 item = self._get()
95 if was_full:
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000096 self.fsema.release()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000097 if not self._empty():
Guido van Rossum7e6d18c1998-04-29 14:29:32 +000098 self.esema.release()
99 self.mutex.release()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000100 return item
Guido van Rossum9022fce1992-08-25 12:30:44 +0000101
Guido van Rossum9e1721f1999-02-08 18:34:01 +0000102 def get_nowait(self):
103 """Remove and return an item from the queue without blocking.
Guido van Rossum9022fce1992-08-25 12:30:44 +0000104
Guido van Rossum9e1721f1999-02-08 18:34:01 +0000105 Only get an item if one is immediately available. Otherwise
106 raise the Empty exception.
107 """
108 return self.get(0)
Guido van Rossum9022fce1992-08-25 12:30:44 +0000109
Barry Warsaw3d96d521997-11-20 19:56:38 +0000110 # Override these methods to implement other queue organizations
111 # (e.g. stack or priority queue).
112 # These will only be called with appropriate locks held
Guido van Rossum9022fce1992-08-25 12:30:44 +0000113
Barry Warsaw3d96d521997-11-20 19:56:38 +0000114 # Initialize the queue representation
115 def _init(self, maxsize):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000116 self.maxsize = maxsize
117 self.queue = []
Guido van Rossum9022fce1992-08-25 12:30:44 +0000118
Barry Warsaw3d96d521997-11-20 19:56:38 +0000119 def _qsize(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000120 return len(self.queue)
Guido van Rossum9022fce1992-08-25 12:30:44 +0000121
Barry Warsaw3d96d521997-11-20 19:56:38 +0000122 # Check wheter the queue is empty
123 def _empty(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000124 return not self.queue
Guido van Rossum9022fce1992-08-25 12:30:44 +0000125
Barry Warsaw3d96d521997-11-20 19:56:38 +0000126 # Check whether the queue is full
127 def _full(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000128 return self.maxsize > 0 and len(self.queue) == self.maxsize
Guido van Rossum9022fce1992-08-25 12:30:44 +0000129
Barry Warsaw3d96d521997-11-20 19:56:38 +0000130 # Put a new item in the queue
131 def _put(self, item):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000132 self.queue.append(item)
Guido van Rossum9022fce1992-08-25 12:30:44 +0000133
Barry Warsaw3d96d521997-11-20 19:56:38 +0000134 # Get an item from the queue
135 def _get(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000136 item = self.queue[0]
137 del self.queue[0]
138 return item