cpython/Lib/dos-8x3/queue.py

139 lines
4.0 KiB
Python
Raw Normal View History

2000-05-08 14:31:04 -03:00
"""A multi-producer, multi-consumer queue."""
1997-11-26 11:44:34 -04:00
# define this exception to be compatible with Python 1.5's class
# exceptions, but also when -X option is used.
try:
class Empty(Exception):
1998-03-26 18:14:20 -04:00
pass
1999-02-09 14:40:13 -04:00
class Full(Exception):
pass
1997-11-26 11:44:34 -04:00
except TypeError:
# string based exceptions
1999-02-09 14:40:13 -04:00
# exception raised by get(block=0)/get_nowait()
Empty = 'Queue.Empty'
# exception raised by put(block=0)/put_nowait()
Full = 'Queue.Full'
class Queue:
2000-05-08 14:31:04 -03:00
def __init__(self, maxsize=0):
1998-03-26 18:14:20 -04:00
"""Initialize a queue object with a given maximum size.
1997-11-26 11:44:34 -04:00
1998-03-26 18:14:20 -04:00
If maxsize is <= 0, the queue size is infinite.
"""
import thread
self._init(maxsize)
self.mutex = thread.allocate_lock()
self.esema = thread.allocate_lock()
1998-08-11 23:38:11 -03:00
self.esema.acquire()
1998-03-26 18:14:20 -04:00
self.fsema = thread.allocate_lock()
1997-11-26 11:44:34 -04:00
def qsize(self):
1999-02-09 14:40:13 -04:00
"""Return the approximate size of the queue (not reliable!)."""
1998-08-11 23:38:11 -03:00
self.mutex.acquire()
1998-03-26 18:14:20 -04:00
n = self._qsize()
1998-08-11 23:38:11 -03:00
self.mutex.release()
1998-03-26 18:14:20 -04:00
return n
1997-11-26 11:44:34 -04:00
def empty(self):
1999-02-09 14:40:13 -04:00
"""Return 1 if the queue is empty, 0 otherwise (not reliable!)."""
1998-08-11 23:38:11 -03:00
self.mutex.acquire()
1998-03-26 18:14:20 -04:00
n = self._empty()
1998-08-11 23:38:11 -03:00
self.mutex.release()
1998-03-26 18:14:20 -04:00
return n
1997-11-26 11:44:34 -04:00
def full(self):
1999-02-09 14:40:13 -04:00
"""Return 1 if the queue is full, 0 otherwise (not reliable!)."""
1998-08-11 23:38:11 -03:00
self.mutex.acquire()
1998-03-26 18:14:20 -04:00
n = self._full()
1998-08-11 23:38:11 -03:00
self.mutex.release()
1998-03-26 18:14:20 -04:00
return n
1997-11-26 11:44:34 -04:00
1999-02-09 14:40:13 -04:00
def put(self, item, block=1):
1998-04-09 18:47:39 -03:00
"""Put an item into the queue.
1999-02-09 14:40:13 -04:00
If optional arg 'block' is 1 (the default), block if
necessary until a free slot is available. Otherwise (block
is 0), put an item on the queue if a free slot is immediately
available, else raise the Full exception.
"""
if block:
self.fsema.acquire()
elif not self.fsema.acquire(0):
raise Full
1998-08-11 23:38:11 -03:00
self.mutex.acquire()
1998-03-26 18:14:20 -04:00
was_empty = self._empty()
self._put(item)
if was_empty:
1998-08-11 23:38:11 -03:00
self.esema.release()
1998-03-26 18:14:20 -04:00
if not self._full():
1998-08-11 23:38:11 -03:00
self.fsema.release()
self.mutex.release()
1997-11-26 11:44:34 -04:00
1999-02-09 14:40:13 -04:00
def put_nowait(self, item):
"""Put an item into the queue without blocking.
1998-04-09 18:47:39 -03:00
1999-02-09 14:40:13 -04:00
Only enqueue the item if a free slot is immediately available.
Otherwise raise the Full exception.
1998-03-26 18:14:20 -04:00
"""
1999-02-09 14:40:13 -04:00
return self.put(item, 0)
1997-11-26 11:44:34 -04:00
1999-02-09 14:40:13 -04:00
def get(self, block=1):
"""Remove and return an item from the queue.
1998-04-09 18:47:39 -03:00
1999-02-09 14:40:13 -04:00
If optional arg 'block' is 1 (the default), block if
necessary until an item is available. Otherwise (block is 0),
return an item if one is immediately available, else raise the
Empty exception.
1998-03-26 18:14:20 -04:00
"""
1999-02-09 14:40:13 -04:00
if block:
self.esema.acquire()
elif not self.esema.acquire(0):
1998-03-26 18:14:20 -04:00
raise Empty
1999-02-09 14:40:13 -04:00
self.mutex.acquire()
1998-03-26 18:14:20 -04:00
was_full = self._full()
item = self._get()
if was_full:
1998-08-11 23:38:11 -03:00
self.fsema.release()
1998-03-26 18:14:20 -04:00
if not self._empty():
1998-08-11 23:38:11 -03:00
self.esema.release()
self.mutex.release()
1998-03-26 18:14:20 -04:00
return item
1997-11-26 11:44:34 -04:00
1999-02-09 14:40:13 -04:00
def get_nowait(self):
"""Remove and return an item from the queue without blocking.
1997-11-26 11:44:34 -04:00
1999-02-09 14:40:13 -04:00
Only get an item if one is immediately available. Otherwise
raise the Empty exception.
"""
return self.get(0)
1997-11-26 11:44:34 -04:00
# Override these methods to implement other queue organizations
# (e.g. stack or priority queue).
# These will only be called with appropriate locks held
# Initialize the queue representation
def _init(self, maxsize):
1998-03-26 18:14:20 -04:00
self.maxsize = maxsize
self.queue = []
1997-11-26 11:44:34 -04:00
def _qsize(self):
1998-03-26 18:14:20 -04:00
return len(self.queue)
1997-11-26 11:44:34 -04:00
2000-06-28 11:48:01 -03:00
# Check whether the queue is empty
1997-11-26 11:44:34 -04:00
def _empty(self):
1998-03-26 18:14:20 -04:00
return not self.queue
1997-11-26 11:44:34 -04:00
# Check whether the queue is full
def _full(self):
1998-03-26 18:14:20 -04:00
return self.maxsize > 0 and len(self.queue) == self.maxsize
1997-11-26 11:44:34 -04:00
# Put a new item in the queue
def _put(self, item):
1998-03-26 18:14:20 -04:00
self.queue.append(item)
1997-11-26 11:44:34 -04:00
# Get an item from the queue
def _get(self):
1998-03-26 18:14:20 -04:00
item = self.queue[0]
del self.queue[0]
return item