My partner and I are beginning to believe there could be a desync possibility in the lock free queue we have written, but we would like some fresh eyes on the subject. What are your thoughts on our design?
// nolockqueue.hpp:
#ifndef NOLOCKQUEUE_HPP
#define NOLOCKQUEUE_HPP
template<typename T>
class noLockQueue {
public:
noLockQueue();
~noLockQueue();
void push(const T dataVar);
bool pop(T &dataVar);
private:
struct node {
node(T dataPassed) : dataVar(dataPassed), next(NULL) {};
T dataVar;
node* next;
};
node* topOfList;
node* bottomOfList;
};
template<typename T>
noLockQueue<T>::noLockQueue() {
topOfList = NULL;
bottomOfList = NULL;
}
template<typename T>
noLockQueue<T>::~noLockQueue() {
node* temp;
while (topOfList != NULL) {
temp = topOfList->next;
delete topOfList;
topOfList = temp;
}
if (bottomOfList != NULL)
throw("Not All Nodes Deleted - nolockqueue/38/.cpp"); // TODO: Strange error to throw.
}
template<typename T>
void noLockQueue<T>::push(const T dataVar) {
if (topOfList == NULL) {
topOfList = bottomOfList = new node(dataVar);
return;
} else {
bottomOfList->next = new node(dataVar);
bottomOfList = bottomOfList->next;
}
}
template<typename T>
bool noLockQueue<T>::pop(T &dataVar) {
if (topOfList == NULL)
return false;
dataVar = topOfList->dataVar;
node* temp = topOfList->next;
delete topOfList;
topOfList = temp;
return true;
}
#endif
// main.cpp (purely a test unit):
#include <iostream>
#include <thread>
#include "nolockqueue.hpp"
#include <windows.h> // For Sleep().
noLockQueue<int> queue;
void threadFunc() {
int var = 0;
Sleep(10);
while (queue.pop(var)) {
std::cout << "\nPopped: " << var;
Sleep(1);
}
}
int main(int argc, char* argv[]) {
std::thread myThread(threadFunc);
for (int i = 0; i < 1000; ++i) {
queue.push(i);
std::cout << "\nPushed: " << i;
Sleep(1);
}
myThread.join();
std::cin >> argc;
return 0;
}