| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/assert.h" | 5 #include "vm/assert.h" |
| 6 #include "vm/message_queue.h" | 6 #include "vm/message_queue.h" |
| 7 #include "vm/unit_test.h" | 7 #include "vm/unit_test.h" |
| 8 | 8 |
| 9 namespace dart { | 9 namespace dart { |
| 10 | 10 |
| 11 | 11 |
| 12 // Provide access to private members of MessageQueue for testing. | 12 // Provide access to private members of MessageQueue for testing. |
| 13 class MessageQueueTestPeer { | 13 class MessageQueueTestPeer { |
| 14 public: | 14 public: |
| 15 explicit MessageQueueTestPeer(MessageQueue* queue) : queue_(queue) {} | 15 explicit MessageQueueTestPeer(MessageQueue* queue) : queue_(queue) {} |
| 16 | 16 |
| 17 bool HasMessage() const { return queue_->head_ != NULL; } | 17 bool HasMessage() const { return queue_->head_ != NULL; } |
| 18 | 18 |
| 19 private: | 19 private: |
| 20 MessageQueue* queue_; | 20 MessageQueue* queue_; |
| 21 }; | 21 }; |
| 22 | 22 |
| 23 | 23 |
| 24 static Dart_Message AllocMsg(const char* str) { |
| 25 return reinterpret_cast<Dart_Message>(strdup(str)); |
| 26 } |
| 27 |
| 28 |
| 24 TEST_CASE(MessageQueue_BasicOperations) { | 29 TEST_CASE(MessageQueue_BasicOperations) { |
| 25 MessageQueue queue; | 30 MessageQueue queue; |
| 26 MessageQueueTestPeer queue_peer(&queue); | 31 MessageQueueTestPeer queue_peer(&queue); |
| 27 EXPECT(!queue_peer.HasMessage()); | 32 EXPECT(!queue_peer.HasMessage()); |
| 28 | 33 |
| 29 Dart_Port port = 1; | 34 Dart_Port port = 1; |
| 30 | 35 |
| 31 // Add two messages. | 36 // Add two messages. |
| 32 PortMessage* msg1 = new PortMessage(port, 0, strdup("msg1")); | 37 PortMessage* msg1 = new PortMessage(port, 0, AllocMsg("msg1")); |
| 33 queue.Enqueue(msg1); | 38 queue.Enqueue(msg1); |
| 34 EXPECT(queue_peer.HasMessage()); | 39 EXPECT(queue_peer.HasMessage()); |
| 35 | 40 |
| 36 PortMessage* msg2 = new PortMessage(port, 0, strdup("msg2")); | 41 PortMessage* msg2 = new PortMessage(port, 0, AllocMsg("msg2")); |
| 37 queue.Enqueue(msg2); | 42 queue.Enqueue(msg2); |
| 38 EXPECT(queue_peer.HasMessage()); | 43 EXPECT(queue_peer.HasMessage()); |
| 39 | 44 |
| 40 // Remove two messages. | 45 // Remove two messages. |
| 41 PortMessage* msg = queue.Dequeue(0); | 46 PortMessage* msg = queue.Dequeue(0); |
| 42 EXPECT(msg != NULL); | 47 EXPECT(msg != NULL); |
| 43 EXPECT_STREQ("msg1", reinterpret_cast<char*>(msg->data())); | 48 EXPECT_STREQ("msg1", reinterpret_cast<char*>(msg->data())); |
| 44 EXPECT(queue_peer.HasMessage()); | 49 EXPECT(queue_peer.HasMessage()); |
| 45 | 50 |
| 46 msg = queue.Dequeue(0); | 51 msg = queue.Dequeue(0); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 while (shared_queue == NULL) { | 116 while (shared_queue == NULL) { |
| 112 MonitorLocker ml(sync); | 117 MonitorLocker ml(sync); |
| 113 ml.Wait(5); | 118 ml.Wait(5); |
| 114 } | 119 } |
| 115 ASSERT(shared_queue != NULL); | 120 ASSERT(shared_queue != NULL); |
| 116 | 121 |
| 117 // Pile up three messages before the other thread runs. | 122 // Pile up three messages before the other thread runs. |
| 118 for (int i = 0; i < 3; i++) { | 123 for (int i = 0; i < 3; i++) { |
| 119 int* data = reinterpret_cast<int*>(malloc(sizeof(*data))); | 124 int* data = reinterpret_cast<int*>(malloc(sizeof(*data))); |
| 120 *data = i+1000; | 125 *data = i+1000; |
| 121 PortMessage* msg = new PortMessage(i+10, i+100, data); | 126 PortMessage* msg = |
| 127 new PortMessage(i+10, i+100, reinterpret_cast<Dart_Message>(data)); |
| 122 shared_queue->Enqueue(msg); | 128 shared_queue->Enqueue(msg); |
| 123 } | 129 } |
| 124 | 130 |
| 125 // Wake the other thread and have it start consuming messages. | 131 // Wake the other thread and have it start consuming messages. |
| 126 { | 132 { |
| 127 MonitorLocker ml(sync); | 133 MonitorLocker ml(sync); |
| 128 ml.Notify(); | 134 ml.Notify(); |
| 129 } | 135 } |
| 130 | 136 |
| 131 // Add a few more messages after sleeping to allow the other thread | 137 // Add a few more messages after sleeping to allow the other thread |
| 132 // to potentially exercise the blocking code path in Dequeue. | 138 // to potentially exercise the blocking code path in Dequeue. |
| 133 OS::Sleep(5); | 139 OS::Sleep(5); |
| 134 for (int i = 0; i < 3; i++) { | 140 for (int i = 0; i < 3; i++) { |
| 135 int* data = reinterpret_cast<int*>(malloc(sizeof(*data))); | 141 int* data = reinterpret_cast<int*>(malloc(sizeof(*data))); |
| 136 *data = i+2000; | 142 *data = i+2000; |
| 137 PortMessage* msg = new PortMessage(i+20, i+200, data); | 143 PortMessage* msg = |
| 144 new PortMessage(i+20, i+200, reinterpret_cast<Dart_Message>(data)); |
| 138 shared_queue->Enqueue(msg); | 145 shared_queue->Enqueue(msg); |
| 139 } | 146 } |
| 140 | 147 |
| 141 sync = NULL; | 148 sync = NULL; |
| 142 delete sync; | 149 delete sync; |
| 143 | 150 |
| 144 // Give the spawned thread enough time to properly exit. | 151 // Give the spawned thread enough time to properly exit. |
| 145 OS::Sleep(20); | 152 OS::Sleep(20); |
| 146 } | 153 } |
| 147 | 154 |
| 148 | 155 |
| 149 TEST_CASE(MessageQueue_FlushAll) { | 156 TEST_CASE(MessageQueue_FlushAll) { |
| 150 MessageQueue queue; | 157 MessageQueue queue; |
| 151 MessageQueueTestPeer queue_peer(&queue); | 158 MessageQueueTestPeer queue_peer(&queue); |
| 152 Dart_Port port1 = 1; | 159 Dart_Port port1 = 1; |
| 153 Dart_Port port2 = 2; | 160 Dart_Port port2 = 2; |
| 154 | 161 |
| 155 // Add two messages. | 162 // Add two messages. |
| 156 PortMessage* msg1 = new PortMessage(port1, 0, strdup("msg1")); | 163 PortMessage* msg1 = new PortMessage(port1, 0, AllocMsg("msg1")); |
| 157 queue.Enqueue(msg1); | 164 queue.Enqueue(msg1); |
| 158 PortMessage* msg2 = new PortMessage(port2, 0, strdup("msg2")); | 165 PortMessage* msg2 = new PortMessage(port2, 0, AllocMsg("msg2")); |
| 159 queue.Enqueue(msg2); | 166 queue.Enqueue(msg2); |
| 160 | 167 |
| 161 EXPECT(queue_peer.HasMessage()); | 168 EXPECT(queue_peer.HasMessage()); |
| 162 queue.FlushAll(); | 169 queue.FlushAll(); |
| 163 EXPECT(!queue_peer.HasMessage()); | 170 EXPECT(!queue_peer.HasMessage()); |
| 164 | 171 |
| 165 // msg1 and msg2 already delete by FlushAll. | 172 // msg1 and msg2 already delete by FlushAll. |
| 166 } | 173 } |
| 167 | 174 |
| 168 | 175 |
| 169 TEST_CASE(MessageQueue_Flush) { | 176 TEST_CASE(MessageQueue_Flush) { |
| 170 MessageQueue queue; | 177 MessageQueue queue; |
| 171 MessageQueueTestPeer queue_peer(&queue); | 178 MessageQueueTestPeer queue_peer(&queue); |
| 172 Dart_Port port1 = 1; | 179 Dart_Port port1 = 1; |
| 173 Dart_Port port2 = 2; | 180 Dart_Port port2 = 2; |
| 174 | 181 |
| 175 // Add two messages on different ports. | 182 // Add two messages on different ports. |
| 176 PortMessage* msg1 = new PortMessage(port1, 0, strdup("msg1")); | 183 PortMessage* msg1 = new PortMessage(port1, 0, AllocMsg("msg1")); |
| 177 queue.Enqueue(msg1); | 184 queue.Enqueue(msg1); |
| 178 PortMessage* msg2 = new PortMessage(port2, 0, strdup("msg2")); | 185 PortMessage* msg2 = new PortMessage(port2, 0, AllocMsg("msg2")); |
| 179 queue.Enqueue(msg2); | 186 queue.Enqueue(msg2); |
| 180 EXPECT(queue_peer.HasMessage()); | 187 EXPECT(queue_peer.HasMessage()); |
| 181 | 188 |
| 182 queue.Flush(port1); | 189 queue.Flush(port1); |
| 183 | 190 |
| 184 // One message is left in the queue. | 191 // One message is left in the queue. |
| 185 EXPECT(queue_peer.HasMessage()); | 192 EXPECT(queue_peer.HasMessage()); |
| 186 PortMessage* msg = queue.Dequeue(0); | 193 PortMessage* msg = queue.Dequeue(0); |
| 187 EXPECT(msg != NULL); | 194 EXPECT(msg != NULL); |
| 188 EXPECT_STREQ("msg2", reinterpret_cast<char*>(msg->data())); | 195 EXPECT_STREQ("msg2", reinterpret_cast<char*>(msg->data())); |
| 189 | 196 |
| 190 EXPECT(!queue_peer.HasMessage()); | 197 EXPECT(!queue_peer.HasMessage()); |
| 191 | 198 |
| 192 // msg1 is already deleted by Flush. | 199 // msg1 is already deleted by Flush. |
| 193 delete msg2; | 200 delete msg2; |
| 194 } | 201 } |
| 195 | 202 |
| 196 | 203 |
| 197 TEST_CASE(MessageQueue_Flush_MultipleMessages) { | 204 TEST_CASE(MessageQueue_Flush_MultipleMessages) { |
| 198 MessageQueue queue; | 205 MessageQueue queue; |
| 199 MessageQueueTestPeer queue_peer(&queue); | 206 MessageQueueTestPeer queue_peer(&queue); |
| 200 Dart_Port port1 = 1; | 207 Dart_Port port1 = 1; |
| 201 | 208 |
| 202 PortMessage* msg1 = new PortMessage(port1, 0, strdup("msg1")); | 209 PortMessage* msg1 = new PortMessage(port1, 0, AllocMsg("msg1")); |
| 203 queue.Enqueue(msg1); | 210 queue.Enqueue(msg1); |
| 204 PortMessage* msg2 = new PortMessage(port1, 0, strdup("msg2")); | 211 PortMessage* msg2 = new PortMessage(port1, 0, AllocMsg("msg2")); |
| 205 queue.Enqueue(msg2); | 212 queue.Enqueue(msg2); |
| 206 EXPECT(queue_peer.HasMessage()); | 213 EXPECT(queue_peer.HasMessage()); |
| 207 | 214 |
| 208 queue.Flush(port1); | 215 queue.Flush(port1); |
| 209 | 216 |
| 210 // Queue is empty. | 217 // Queue is empty. |
| 211 EXPECT(!queue_peer.HasMessage()); | 218 EXPECT(!queue_peer.HasMessage()); |
| 212 // msg1 and msg2 are already deleted by Flush. | 219 // msg1 and msg2 are already deleted by Flush. |
| 213 } | 220 } |
| 214 | 221 |
| 215 | 222 |
| 216 TEST_CASE(MessageQueue_Flush_EmptyQueue) { | 223 TEST_CASE(MessageQueue_Flush_EmptyQueue) { |
| 217 MessageQueue queue; | 224 MessageQueue queue; |
| 218 MessageQueueTestPeer queue_peer(&queue); | 225 MessageQueueTestPeer queue_peer(&queue); |
| 219 Dart_Port port1 = 1; | 226 Dart_Port port1 = 1; |
| 220 | 227 |
| 221 EXPECT(!queue_peer.HasMessage()); | 228 EXPECT(!queue_peer.HasMessage()); |
| 222 queue.Flush(port1); | 229 queue.Flush(port1); |
| 223 | 230 |
| 224 // Queue is still empty. | 231 // Queue is still empty. |
| 225 EXPECT(!queue_peer.HasMessage()); | 232 EXPECT(!queue_peer.HasMessage()); |
| 226 } | 233 } |
| 227 | 234 |
| 228 | 235 |
| 229 } // namespace dart | 236 } // namespace dart |
| OLD | NEW |