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/message_queue.h" | 5 #include "vm/message.h" |
6 | 6 |
7 namespace dart { | 7 namespace dart { |
8 | 8 |
| 9 DECLARE_FLAG(bool, trace_isolates); |
| 10 |
| 11 |
| 12 MessageHandler::MessageHandler() |
| 13 : live_ports_(0), |
| 14 queue_(new MessageQueue()) { |
| 15 ASSERT(queue_ != NULL); |
| 16 } |
| 17 |
| 18 |
| 19 MessageHandler::~MessageHandler() { |
| 20 delete queue_; |
| 21 } |
| 22 |
| 23 |
| 24 const char* MessageHandler::name() const { |
| 25 return "<unnamed>"; |
| 26 } |
| 27 |
| 28 |
| 29 #if defined(DEBUG) |
| 30 void MessageHandler::CheckAccess() { |
| 31 // By default there is no checking. |
| 32 } |
| 33 #endif |
| 34 |
| 35 |
| 36 void MessageHandler::MessageNotify(Message::Priority priority) { |
| 37 // By default, there is no custom message notification. |
| 38 } |
| 39 |
| 40 |
| 41 void MessageHandler::PostMessage(Message* message) { |
| 42 if (FLAG_trace_isolates) { |
| 43 const char* source_name = "<native code>"; |
| 44 Isolate* source_isolate = Isolate::Current(); |
| 45 if (source_isolate) { |
| 46 source_name = source_isolate->name(); |
| 47 } |
| 48 OS::Print("[>] Posting message:\n" |
| 49 "\tsource: %s\n" |
| 50 "\treply_port: %lld\n" |
| 51 "\tdest: %s\n" |
| 52 "\tdest_port: %lld\n", |
| 53 source_name, message->reply_port(), name(), message->dest_port()); |
| 54 } |
| 55 |
| 56 Message::Priority priority = message->priority(); |
| 57 queue()->Enqueue(message); |
| 58 message = NULL; // Do not access message. May have been deleted. |
| 59 |
| 60 // Invoke any custom message notification. |
| 61 MessageNotify(priority); |
| 62 } |
| 63 |
| 64 |
| 65 void MessageHandler::ClosePort(Dart_Port port) { |
| 66 queue()->Flush(port); |
| 67 } |
| 68 |
| 69 |
| 70 void MessageHandler::CloseAllPorts() { |
| 71 queue()->FlushAll(); |
| 72 } |
| 73 |
| 74 |
9 MessageQueue::MessageQueue() { | 75 MessageQueue::MessageQueue() { |
10 for (int p = Message::kFirstPriority; p < Message::kNumPriorities; p++) { | 76 for (int p = Message::kFirstPriority; p < Message::kNumPriorities; p++) { |
11 head_[p] = NULL; | 77 head_[p] = NULL; |
12 tail_[p] = NULL; | 78 tail_[p] = NULL; |
13 } | 79 } |
14 } | 80 } |
15 | 81 |
16 | 82 |
17 MessageQueue::~MessageQueue() { | 83 MessageQueue::~MessageQueue() { |
18 // Ensure that all pending messages have been released. | 84 // Ensure that all pending messages have been released. |
19 #if defined(DEBUG) | 85 #if defined(DEBUG) |
20 for (int p = Message::kFirstPriority; p < Message::kNumPriorities; p++) { | 86 for (int p = Message::kFirstPriority; p < Message::kNumPriorities; p++) { |
21 ASSERT(head_[p] == NULL); | 87 ASSERT(head_[p] == NULL); |
22 } | 88 } |
23 #endif | 89 #endif |
24 } | 90 } |
25 | 91 |
26 | 92 |
27 void MessageQueue::Enqueue(Message* msg) { | 93 void MessageQueue::Enqueue(Message* msg) { |
28 // TODO(turnidge): Add a scoped locker for monitors which is not a | 94 MonitorLocker ml(&monitor_); |
29 // stack resource. This would probably be useful in the platform | |
30 // headers. | |
31 monitor_.Enter(); | |
32 | |
33 Message::Priority p = msg->priority(); | 95 Message::Priority p = msg->priority(); |
34 // Make sure messages are not reused. | 96 // Make sure messages are not reused. |
35 ASSERT(msg->next_ == NULL); | 97 ASSERT(msg->next_ == NULL); |
36 if (head_[p] == NULL) { | 98 if (head_[p] == NULL) { |
37 // Only element in the queue. | 99 // Only element in the queue. |
38 head_[p] = msg; | 100 head_[p] = msg; |
39 tail_[p] = msg; | 101 tail_[p] = msg; |
40 | 102 |
41 // We only need to notify if the queue was empty. | 103 // We only need to notify if the queue was empty. |
42 monitor_.Notify(); | 104 monitor_.Notify(); |
43 } else { | 105 } else { |
44 ASSERT(tail_[p] != NULL); | 106 ASSERT(tail_[p] != NULL); |
45 // Append at the tail. | 107 // Append at the tail. |
46 tail_[p]->next_ = msg; | 108 tail_[p]->next_ = msg; |
47 tail_[p] = msg; | 109 tail_[p] = msg; |
48 } | 110 } |
49 | |
50 monitor_.Exit(); | |
51 } | 111 } |
52 | 112 |
53 Message* MessageQueue::DequeueNoWait() { | 113 Message* MessageQueue::DequeueNoWait() { |
54 MonitorLocker ml(&monitor_); | 114 MonitorLocker ml(&monitor_); |
55 return DequeueNoWaitHoldsLock(); | 115 return DequeueNoWaitHoldsLock(); |
56 } | 116 } |
57 | 117 |
58 Message* MessageQueue::DequeueNoWaitHoldsLock() { | 118 Message* MessageQueue::DequeueNoWaitHoldsLock() { |
59 // Look for the highest priority available message. | 119 // Look for the highest priority available message. |
60 for (int p = Message::kNumPriorities-1; p >= Message::kFirstPriority; p--) { | 120 for (int p = Message::kNumPriorities-1; p >= Message::kFirstPriority; p--) { |
(...skipping 10 matching lines...) Expand all Loading... |
71 return result; | 131 return result; |
72 } | 132 } |
73 } | 133 } |
74 return NULL; | 134 return NULL; |
75 } | 135 } |
76 | 136 |
77 | 137 |
78 Message* MessageQueue::Dequeue(int64_t millis) { | 138 Message* MessageQueue::Dequeue(int64_t millis) { |
79 ASSERT(millis >= 0); | 139 ASSERT(millis >= 0); |
80 MonitorLocker ml(&monitor_); | 140 MonitorLocker ml(&monitor_); |
81 | |
82 Message* result = DequeueNoWaitHoldsLock(); | 141 Message* result = DequeueNoWaitHoldsLock(); |
83 if (result == NULL) { | 142 if (result == NULL) { |
84 // No message available at any priority. | 143 // No message available at any priority. |
85 ml.Wait(millis); | 144 monitor_.Wait(millis); |
86 result = DequeueNoWaitHoldsLock(); | 145 result = DequeueNoWaitHoldsLock(); |
87 } | 146 } |
88 return result; | 147 return result; |
89 } | 148 } |
90 | 149 |
91 | 150 |
92 void MessageQueue::Flush(Dart_Port port) { | 151 void MessageQueue::Flush(Dart_Port port) { |
93 MonitorLocker ml(&monitor_); | 152 MonitorLocker ml(&monitor_); |
94 for (int p = Message::kFirstPriority; p < Message::kNumPriorities; p++) { | 153 for (int p = Message::kFirstPriority; p < Message::kNumPriorities; p++) { |
95 Message* cur = head_[p]; | 154 Message* cur = head_[p]; |
(...skipping 29 matching lines...) Expand all Loading... |
125 while (cur != NULL) { | 184 while (cur != NULL) { |
126 Message* next = cur->next_; | 185 Message* next = cur->next_; |
127 delete cur; | 186 delete cur; |
128 cur = next; | 187 cur = next; |
129 } | 188 } |
130 } | 189 } |
131 } | 190 } |
132 | 191 |
133 | 192 |
134 } // namespace dart | 193 } // namespace dart |
OLD | NEW |