Example #1
0
class Buffer(object):
    def __init__(self, buffer_size=5):
        self.buffer_size = buffer_size
        self.free_slots = QSemaphore(self.buffer_size)
        self.used_slots = QSemaphore(0)
        self.clear_buffer_add = QSemaphore(1)
        self.clear_buffer_get = QSemaphore(1)
        self.queue_mutex = QMutex()
        self.queue = Queue(self.buffer_size)

    def add(self, data, drop_if_full=False):
        self.clear_buffer_add.acquire()
        if drop_if_full:
            if self.free_slots.tryAcquire():
                self.queue_mutex.lock()
                self.queue.put(data)
                self.queue_mutex.unlock()
                self.used_slots.release()
        else:
            self.free_slots.acquire()
            self.queue_mutex.lock()
            self.queue.put(data)
            self.queue_mutex.unlock()
            self.used_slots.release()

        self.clear_buffer_add.release()

    def get(self):
        # acquire semaphores
        self.clear_buffer_get.acquire()
        self.used_slots.acquire()
        self.queue_mutex.lock()
        data = self.queue.get()
        self.queue_mutex.unlock()
        # release semaphores
        self.free_slots.release()
        self.clear_buffer_get.release()
        # return item to caller
        return data

    def clear(self):
        # check if buffer contains items
        if self.queue.qsize() > 0:
            # stop adding items to buffer (will return false if an item is currently being added to the buffer)
            if self.clear_buffer_add.tryAcquire():
                # stop taking items from buffer (will return false if an item is currently being taken from the buffer)
                if self.clear_buffer_get.tryAcquire():
                    # release all remaining slots in queue
                    self.free_slots.release(self.queue.qsize())
                    # acquire all queue slots
                    self.free_slots.acquire(self.buffer_size)
                    # reset used_slots to zero
                    self.used_slots.acquire(self.queue.qsize())
                    # clear buffer
                    for _ in range(self.queue.qsize()):
                        self.queue.get()
                    # release all slots
                    self.free_slots.release(self.buffer_size)
                    # allow get method to resume
                    self.clear_buffer_get.release()
                else:
                    return False
                # allow add method to resume
                self.clear_buffer_add.release()
                return True
            else:
                return False
        else:
            return False

    def size(self):
        return self.queue.qsize()

    def maxsize(self):
        return self.buffer_size

    def isfull(self):
        return self.queue.qsize() == self.buffer_size

    def isempty(self):
        return self.queue.qsize() == 0
Example #2
0
class Buffer(object):
    def __init__(self, size):
        # Save buffer size
        self.bufferSize = size
        # Create semaphores
        self.freeSlots = QSemaphore(self.bufferSize)
        self.usedSlots = QSemaphore(0)
        self.clearBuffer_add = QSemaphore(1)
        self.clearBuffer_get = QSemaphore(1)
        # Create mutex
        self.queueProtect = QMutex()
        # Create queue
        self.queue = Queue(self.bufferSize)

    def add(self, data, dropIfFull=False):
        # Acquire semaphore
        self.clearBuffer_add.acquire()
        # If dropping is enabled, do not block if buffer is full
        if dropIfFull:
            # Try and acquire semaphore to add item

            # Drop new frame
            # if self.freeSlots.tryAcquire():
            #     # Add item to queue
            #     self.queueProtect.lock()
            #     self.queue.put(data)
            #     self.queueProtect.unlock()
            #     # Release semaphore
            #     self.usedSlots.release()

            # Drop oldest frame
            ret = self.freeSlots.tryAcquire()
            self.queueProtect.lock()
            if not ret:
                self.queue.get()
            else:
                # Release semaphore
                self.usedSlots.release()
            self.queue.put(data)
            self.queueProtect.unlock()
        # If buffer is full, wait on semaphore
        else:
            # Acquire semaphore
            self.freeSlots.acquire()
            # Add item to queue
            self.queueProtect.lock()
            self.queue.put(data)
            self.queueProtect.unlock()
            # Release semaphore
            self.usedSlots.release()
        # Release semaphore
        self.clearBuffer_add.release()

    def get(self):
        # Acquire semaphores
        self.clearBuffer_get.acquire()
        self.usedSlots.acquire()
        # Take item from queue
        self.queueProtect.lock()
        data = self.queue.get()
        self.queueProtect.unlock()
        # Release semaphores
        self.freeSlots.release()
        self.clearBuffer_get.release()
        # Return item to caller
        return data

    def clear(self):
        # Check if buffer contains items
        if self.queue.qsize() > 0:
            # Stop adding items to buffer (will return false if an item is currently being added to the buffer)
            if self.clearBuffer_add.tryAcquire():
                # Stop taking items from buffer (will return false if an item is currently being taken from the buffer)
                if self.clearBuffer_get.tryAcquire():
                    # Release all remaining slots in queue
                    self.freeSlots.release(self.queue.qsize())
                    # Acquire all queue slots
                    self.freeSlots.acquire(self.bufferSize)
                    # Reset usedSlots to zero
                    self.usedSlots.acquire(self.queue.qsize())
                    # Clear buffer
                    for _ in range(self.queue.qsize()):
                        self.queue.get()
                    # Release all slots
                    self.freeSlots.release(self.bufferSize)
                    # Allow get method to resume
                    self.clearBuffer_get.release()
                else:
                    return False
                # Allow add method to resume
                self.clearBuffer_add.release()
                return True
            else:
                return False
        else:
            return False

    def size(self):
        return self.queue.qsize()

    def maxSize(self):
        return self.bufferSize

    def isFull(self):
        return self.queue.qsize() == self.bufferSize

    def isEmpty(self):
        return self.queue.qsize() == 0