Creating ConcurrentLinkedListQueue for C++
[iot2.git] / iotjava / iotrmi / C++ / ConcurrentLinkedListQueue.cpp
1 #include <iostream>
2 #include <thread>
3
4 #include "ConcurrentLinkedListQueue.hpp"
5
6 using namespace std;
7
8
9 Node::Node(void* val) {
10
11         value = val;
12         next = NULL;
13 }
14
15
16 Node::~Node() {
17
18         /*if (next != NULL) {
19                 delete next;
20                 next = NULL;
21         }
22         if (value != NULL) {
23                 delete value;
24                 value = NULL;
25         }*/
26 }
27
28
29 void* Node::getValue() {
30
31         return value;
32 }
33
34
35 Node* Node::getNext() {
36
37         return next;
38 }
39
40
41 void Node::setNext(Node* nxt) {
42
43         next = nxt;
44 }
45
46
47 ConcurrentLinkedListQueue::ConcurrentLinkedListQueue() {
48
49         tail = NULL;
50         head = NULL;
51 }
52
53
54 ConcurrentLinkedListQueue::~ConcurrentLinkedListQueue() {
55
56         void* val = NULL;
57         do {    // Dequeue and free everything up
58                 val = dequeue();
59         } while(val != NULL);
60 }
61
62
63 void ConcurrentLinkedListQueue::enqueue(void* value) {
64
65         lock_guard<mutex> guard(mtx);
66         if (tail == NULL && head == NULL) {     // first element
67                 tail = new Node(value);
68                 head = tail;    // Both tail and head point to the first element
69         } else {        // Next elements
70                 Node* newEl = new Node(value);
71                 tail->setNext(newEl);
72                 tail = newEl;
73         }
74 }
75
76
77 // Return element and remove from list
78 void* ConcurrentLinkedListQueue::dequeue() {
79
80         lock_guard<mutex> guard(mtx);
81         if (tail == NULL && head == NULL) {     // empty
82                 return NULL;
83         } else {
84                 Node* retEl = head;
85                 if (head->getNext() == NULL) {
86                         head = NULL;
87                         tail = NULL;
88                 } else
89                         head = head->getNext();
90                 void* retVal = retEl->getValue();
91                 // Prepare retEl for deletion
92                 retEl->setNext(NULL);
93                 delete retEl;
94                 // Return just the value
95                 return retVal;
96         }
97 }
98
99
100 void enQ(ConcurrentLinkedListQueue* methodQueue, char** test) {
101
102         /*char* test = new char[3];
103         test[0] = 'a';
104         test[1] = 'b';
105         test[2] = 'c';*/
106         void* ptr = test;
107         for(int i=0; i<10; i++ ) {
108                 cout << "Enqueuing: " << test << " address: " << ptr << endl;
109                 methodQueue->enqueue(ptr);
110         }
111 }
112
113
114 void deQ(ConcurrentLinkedListQueue* methodQueue) {
115
116         for(int i=0; i<12; i++) {
117                 void* result = methodQueue->dequeue();
118                 if (result != NULL) {
119                         cout << "Dequeue result: " << result << endl;
120                         cout << "Dequeue result: " << *((char**) result) << endl;               
121                 } else {
122                         cout << "Result is NULL!!! End of queue!" << endl;
123                 }
124         }
125 }
126
127
128 int main(int argc, char *argv[])
129 {
130         ConcurrentLinkedListQueue* methodQueue = new ConcurrentLinkedListQueue();
131         /*cout << "Dequeue result: " << methodQueue->dequeue() << endl;
132         string str = "this is a test string";
133         const char* test = str.c_str();
134         const char** test2 = &test;
135         cout << "Initial result: " << test << endl;
136         cout << "Initial result 2: " << *test2 << endl;
137         void* ptr = &test;
138         cout << "Pointer: " << ptr << endl;
139         methodQueue->enqueue(ptr);
140         methodQueue->enqueue(ptr);
141         void* result = methodQueue->dequeue();
142         cout << "Result: " << result << endl;
143         cout << "Dequeue result: " << *((const char**) result) << endl;
144         void* result2 = methodQueue->dequeue();
145         cout << "Dequeue result: " << *((const char**) result2) << endl;
146         void* result3 = methodQueue->dequeue();
147         cout << "Dequeue result: " << result3 << endl;*/
148         //thread t1,t2;
149
150         //t1 = thread(enQ, methodQueue);
151         //t2 = thread(deQ, methodQueue);
152
153         //t1.join();
154         //t2.join();
155
156         char* test = new char[3];
157         test[0] = 'a';
158         test[1] = 'b';
159         test[2] = 'c';
160         void* ptr = &test;
161         methodQueue->enqueue(ptr);
162         void* result = methodQueue->dequeue();
163         cout << "Dequeue result: " << *((char**) result) << endl;
164
165         thread t1,t2;
166
167         t1 = thread(enQ, methodQueue, &test);
168         t2 = thread(deQ, methodQueue);
169
170         t1.join();
171         t2.join();
172
173         return 0;
174 }
175