Merge branch 'master' of ssh://plrg.eecs.uci.edu/home/git/iot2
[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(char* val, int len) {
10
11         value = val;
12         length = len;
13         next = NULL;
14 }
15
16
17 Node::~Node() {
18
19         /*if (next != NULL) {
20                 delete next;
21                 next = NULL;
22         }
23         if (value != NULL) {
24                 delete value;
25                 value = NULL;
26         }*/
27 }
28
29
30 char* Node::getValue() {
31
32         return value;
33 }
34
35
36 int Node::getLength() {
37
38         return length;
39 }
40
41
42 Node* Node::getNext() {
43
44         return next;
45 }
46
47
48 void Node::setNext(Node* nxt) {
49
50         next = nxt;
51 }
52
53
54 ConcurrentLinkedListQueue::ConcurrentLinkedListQueue() {
55
56         tail = NULL;
57         head = NULL;
58 }
59
60
61 ConcurrentLinkedListQueue::~ConcurrentLinkedListQueue() {
62
63         char* val = NULL;
64         do {    // Dequeue and free everything up
65                 val = dequeue();
66         } while(val != NULL);
67 }
68
69
70 void ConcurrentLinkedListQueue::enqueue(char* value, int length) {
71
72         lock_guard<mutex> guard(queueMutex);
73         if (tail == NULL && head == NULL) {     // first element
74                 tail = new Node(value, length);
75                 head = tail;    // Both tail and head point to the first element
76         } else {        // Next elements
77                 Node* newEl = new Node(value, length);
78                 tail->setNext(newEl);
79                 tail = newEl;
80         }
81 }
82
83
84 // Return element and remove from list
85 char* ConcurrentLinkedListQueue::dequeue() {
86
87         lock_guard<mutex> guard(queueMutex);
88         if (tail == NULL && head == NULL) {     // empty
89                 return NULL;
90         } else {
91                 Node* retEl = head;
92                 if (head->getNext() == NULL) {
93                         head = NULL;
94                         tail = NULL;
95                 } else
96                         head = head->getNext();
97                 char* retVal = retEl->getValue();
98                 // Prepare retEl for deletion
99                 retEl->setNext(NULL);
100                 delete retEl;
101                 // Return just the value
102                 return retVal;
103         }
104 }
105
106 // Return element, length, and remove it from list
107 char* ConcurrentLinkedListQueue::deQAndGetLength(int* length) {
108
109         lock_guard<mutex> guard(queueMutex);
110         if (tail == NULL && head == NULL) {     // empty
111                 *length = 0;
112                 return 0;
113         } else {
114                 Node* retEl = head;
115                 if (head->getNext() == NULL) {
116                         head = NULL;
117                         tail = NULL;
118                 } else
119                         head = head->getNext();
120                 char* retVal = retEl->getValue();
121                 *length = retEl->getLength();
122                 // Prepare retEl for deletion
123                 retEl->setNext(NULL);
124                 delete retEl;
125                 // Return just the value
126                 //cout << "Print bytes inside dequeue: ";
127                 //IoTRMIUtil::printBytes(*((char**) retVal), *length, false);
128                 //cout << "Dequeuing: " << *((char**) retVal) << endl;
129                 //cout << "Dequeuing address: " << std::ref(retVal) << endl;
130                 return retVal;
131         }
132 }
133
134
135