1

I have a template wrapper class around the container std::priority_queue that supports multithreading. The short version of it is below. In this class I employ the function IsReady() that checks whether the element is ready to be popped or not. Implementation of IsReady() depends on the type T.

At first I made IsReady() a class member of PriorityQueue and created a template specialized method for various types T. However, it seems as an incorrect idea to pollute this generic PriorityQueue class with such specializations.

#include <queue>
#include "pthread.h"

enum RV {
    SUCCESS = 0,
    ERROR = 1,
};

template <class T>
class PriorityQueue {

private:

    std::priority_queue<T> __priorityQueue;
    pthread_mutex_t __mutex;
    pthread_cond_t __condition;

public:

    PriorityQueue();
    void Push(T element);
    RV TryPop(T * element);

};

template <class T>
PriorityQueue<T>::PriorityQueue() {
    pthread_mutex_init(&__mutex, NULL);
    pthread_cond_init(&__condition, NULL);
}

template <class T>
void PriorityQueue<T>::Push(T element) {
    pthread_mutex_lock(&__mutex);
    __priorityQueue.push(element);
    pthread_cond_signal(&__condition);
    pthread_mutex_unlock(&__mutex);
}

template <class T>
RV PriorityQueue<T>::TryPop(T * element) {
    pthread_mutex_lock(&__mutex);
    if (__priorityQueue.empty()) {
        pthread_mutex_unlock(&__mutex);
        return ERROR;
    }
    *element = __priorityQueue.top();
    if (!IsReady(*element)) {
        pthread_mutex_unlock(&__mutex);
        return ERROR;
    }
    __priorityQueue.pop();
    pthread_mutex_unlock(&__mutex);
    return SUCCESS;
}

Questions:

1) Is it fine in general to have something like IsReady() methods in such generic classes as PriorityQueue?

2) What is the best option to inject IsReady() method into this class (template specialization, passing function pointer to the constructor of PriorityQueue etc)?

Thank you for your help in advance!

  • 1
    What - in detail - is IsReady supposed to check, and can you avoid the need for IsReady by providing a generic Top function? – Doc Brown Feb 6 '17 at 15:09
  • @Doc Brown For example, type T may be an object that represents a timer and IsReady() checks that the timer is ready to be invoked. In this case, IsReady() compares current system time and time in timer object. – Konstantin Feb 6 '17 at 17:21
  • What do you mean by "is it fine?" Without knowing what "fine" means to you specifically (other than some random internet person's judgement of "acceptable"), that question is unanswerable. – Robert Harvey Feb 6 '17 at 19:31
  • Well, I don't understand why you need a method IsReady for which calls are bound to the mutex of the priority queue. – Doc Brown Feb 6 '17 at 20:08
  • IsReady() creates a race condition. Make sure the operations you wish to perform can be completed using only one call. – Frank Hileman Feb 10 '17 at 21:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.