| 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_handler.h" | 5 #include "vm/message_handler.h" |
| 6 | 6 |
| 7 #include "vm/dart.h" | 7 #include "vm/dart.h" |
| 8 #include "vm/lockers.h" | 8 #include "vm/lockers.h" |
| 9 #include "vm/object.h" | 9 #include "vm/object.h" |
| 10 #include "vm/object_store.h" | 10 #include "vm/object_store.h" |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 return message; | 169 return message; |
| 170 } | 170 } |
| 171 | 171 |
| 172 | 172 |
| 173 void MessageHandler::ClearOOBQueue() { | 173 void MessageHandler::ClearOOBQueue() { |
| 174 oob_queue_->Clear(); | 174 oob_queue_->Clear(); |
| 175 } | 175 } |
| 176 | 176 |
| 177 | 177 |
| 178 MessageHandler::MessageStatus MessageHandler::HandleMessages( | 178 MessageHandler::MessageStatus MessageHandler::HandleMessages( |
| 179 MonitorLocker* ml, |
| 179 bool allow_normal_messages, | 180 bool allow_normal_messages, |
| 180 bool allow_multiple_normal_messages) { | 181 bool allow_multiple_normal_messages) { |
| 181 // TODO(turnidge): Add assert that monitor_ is held here. | 182 // TODO(turnidge): Add assert that monitor_ is held here. |
| 182 | 183 |
| 183 // If isolate() returns NULL StartIsolateScope does nothing. | 184 // If isolate() returns NULL StartIsolateScope does nothing. |
| 184 StartIsolateScope start_isolate(isolate()); | 185 StartIsolateScope start_isolate(isolate()); |
| 185 | 186 |
| 186 MessageStatus max_status = kOK; | 187 MessageStatus max_status = kOK; |
| 187 Message::Priority min_priority = ((allow_normal_messages && !paused()) | 188 Message::Priority min_priority = ((allow_normal_messages && !paused()) |
| 188 ? Message::kNormalPriority | 189 ? Message::kNormalPriority |
| 189 : Message::kOOBPriority); | 190 : Message::kOOBPriority); |
| 190 Message* message = DequeueMessage(min_priority); | 191 Message* message = DequeueMessage(min_priority); |
| 191 while (message != NULL) { | 192 while (message != NULL) { |
| 192 intptr_t message_len = message->len(); | 193 intptr_t message_len = message->len(); |
| 193 if (FLAG_trace_isolates) { | 194 if (FLAG_trace_isolates) { |
| 194 OS::Print("[<] Handling message:\n" | 195 OS::Print("[<] Handling message:\n" |
| 195 "\tlen: %" Pd "\n" | 196 "\tlen: %" Pd "\n" |
| 196 "\thandler: %s\n" | 197 "\thandler: %s\n" |
| 197 "\tport: %" Pd64 "\n", | 198 "\tport: %" Pd64 "\n", |
| 198 message_len, name(), message->dest_port()); | 199 message_len, name(), message->dest_port()); |
| 199 } | 200 } |
| 200 | 201 |
| 201 // Release the monitor_ temporarily while we handle the message. | 202 // Release the monitor_ temporarily while we handle the message. |
| 202 // The monitor was acquired in MessageHandler::TaskCallback(). | 203 // The monitor was acquired in MessageHandler::TaskCallback(). |
| 203 monitor_.Exit(); | 204 ml->Exit(); |
| 204 Message::Priority saved_priority = message->priority(); | 205 Message::Priority saved_priority = message->priority(); |
| 205 Dart_Port saved_dest_port = message->dest_port(); | 206 Dart_Port saved_dest_port = message->dest_port(); |
| 206 MessageStatus status = HandleMessage(message); | 207 MessageStatus status = HandleMessage(message); |
| 207 if (status > max_status) { | 208 if (status > max_status) { |
| 208 max_status = status; | 209 max_status = status; |
| 209 } | 210 } |
| 210 message = NULL; // May be deleted by now. | 211 message = NULL; // May be deleted by now. |
| 211 monitor_.Enter(); | 212 ml->Enter(); |
| 212 if (FLAG_trace_isolates) { | 213 if (FLAG_trace_isolates) { |
| 213 OS::Print("[.] Message handled (%s):\n" | 214 OS::Print("[.] Message handled (%s):\n" |
| 214 "\tlen: %" Pd "\n" | 215 "\tlen: %" Pd "\n" |
| 215 "\thandler: %s\n" | 216 "\thandler: %s\n" |
| 216 "\tport: %" Pd64 "\n", | 217 "\tport: %" Pd64 "\n", |
| 217 MessageStatusString(status), | 218 MessageStatusString(status), |
| 218 message_len, name(), saved_dest_port); | 219 message_len, name(), saved_dest_port); |
| 219 } | 220 } |
| 220 // If we are shutting down, do not process any more messages. | 221 // If we are shutting down, do not process any more messages. |
| 221 if (status == kShutdown) { | 222 if (status == kShutdown) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 247 | 248 |
| 248 | 249 |
| 249 MessageHandler::MessageStatus MessageHandler::HandleNextMessage() { | 250 MessageHandler::MessageStatus MessageHandler::HandleNextMessage() { |
| 250 // We can only call HandleNextMessage when this handler is not | 251 // We can only call HandleNextMessage when this handler is not |
| 251 // assigned to a thread pool. | 252 // assigned to a thread pool. |
| 252 MonitorLocker ml(&monitor_); | 253 MonitorLocker ml(&monitor_); |
| 253 ASSERT(pool_ == NULL); | 254 ASSERT(pool_ == NULL); |
| 254 #if defined(DEBUG) | 255 #if defined(DEBUG) |
| 255 CheckAccess(); | 256 CheckAccess(); |
| 256 #endif | 257 #endif |
| 257 return HandleMessages(true, false); | 258 return HandleMessages(&ml, true, false); |
| 258 } | 259 } |
| 259 | 260 |
| 260 | 261 |
| 261 MessageHandler::MessageStatus MessageHandler::HandleAllMessages() { | 262 MessageHandler::MessageStatus MessageHandler::HandleAllMessages() { |
| 262 // We can only call HandleAllMessages when this handler is not | 263 // We can only call HandleAllMessages when this handler is not |
| 263 // assigned to a thread pool. | 264 // assigned to a thread pool. |
| 264 MonitorLocker ml(&monitor_); | 265 MonitorLocker ml(&monitor_); |
| 265 ASSERT(pool_ == NULL); | 266 ASSERT(pool_ == NULL); |
| 266 #if defined(DEBUG) | 267 #if defined(DEBUG) |
| 267 CheckAccess(); | 268 CheckAccess(); |
| 268 #endif | 269 #endif |
| 269 return HandleMessages(true, true); | 270 return HandleMessages(&ml, true, true); |
| 270 } | 271 } |
| 271 | 272 |
| 272 | 273 |
| 273 MessageHandler::MessageStatus MessageHandler::HandleOOBMessages() { | 274 MessageHandler::MessageStatus MessageHandler::HandleOOBMessages() { |
| 274 if (!oob_message_handling_allowed_) { | 275 if (!oob_message_handling_allowed_) { |
| 275 return kOK; | 276 return kOK; |
| 276 } | 277 } |
| 277 MonitorLocker ml(&monitor_); | 278 MonitorLocker ml(&monitor_); |
| 278 #if defined(DEBUG) | 279 #if defined(DEBUG) |
| 279 CheckAccess(); | 280 CheckAccess(); |
| 280 #endif | 281 #endif |
| 281 return HandleMessages(false, false); | 282 return HandleMessages(&ml, false, false); |
| 282 } | 283 } |
| 283 | 284 |
| 284 | 285 |
| 285 bool MessageHandler::ShouldPauseOnStart(MessageStatus status) const { | 286 bool MessageHandler::ShouldPauseOnStart(MessageStatus status) const { |
| 286 Isolate* owning_isolate = isolate(); | 287 Isolate* owning_isolate = isolate(); |
| 287 if (owning_isolate == NULL) { | 288 if (owning_isolate == NULL) { |
| 288 return false; | 289 return false; |
| 289 } | 290 } |
| 290 // If we are restarting or shutting down, we do not want to honor | 291 // If we are restarting or shutting down, we do not want to honor |
| 291 // should_pause_on_start or should_pause_on_exit. | 292 // should_pause_on_start or should_pause_on_exit. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 320 // We will occasionally release and reacquire this monitor in this | 321 // We will occasionally release and reacquire this monitor in this |
| 321 // function. Whenever we reacquire the monitor we *must* process | 322 // function. Whenever we reacquire the monitor we *must* process |
| 322 // all pending OOB messages, or we may miss a request for vm | 323 // all pending OOB messages, or we may miss a request for vm |
| 323 // shutdown. | 324 // shutdown. |
| 324 MonitorLocker ml(&monitor_); | 325 MonitorLocker ml(&monitor_); |
| 325 if (ShouldPauseOnStart(kOK)) { | 326 if (ShouldPauseOnStart(kOK)) { |
| 326 if (!is_paused_on_start()) { | 327 if (!is_paused_on_start()) { |
| 327 PausedOnStartLocked(true); | 328 PausedOnStartLocked(true); |
| 328 } | 329 } |
| 329 // More messages may have come in before we (re)acquired the monitor. | 330 // More messages may have come in before we (re)acquired the monitor. |
| 330 status = HandleMessages(false, false); | 331 status = HandleMessages(&ml, false, false); |
| 331 if (ShouldPauseOnStart(status)) { | 332 if (ShouldPauseOnStart(status)) { |
| 332 // Still paused. | 333 // Still paused. |
| 333 ASSERT(oob_queue_->IsEmpty()); | 334 ASSERT(oob_queue_->IsEmpty()); |
| 334 task_ = NULL; // No task in queue. | 335 task_ = NULL; // No task in queue. |
| 335 return; | 336 return; |
| 336 } else { | 337 } else { |
| 337 PausedOnStartLocked(false); | 338 PausedOnStartLocked(false); |
| 338 } | 339 } |
| 339 } | 340 } |
| 340 | 341 |
| 341 if (status == kOK) { | 342 if (status == kOK) { |
| 342 if (start_callback_) { | 343 if (start_callback_) { |
| 343 // Initialize the message handler by running its start function, | 344 // Initialize the message handler by running its start function, |
| 344 // if we have one. For an isolate, this will run the isolate's | 345 // if we have one. For an isolate, this will run the isolate's |
| 345 // main() function. | 346 // main() function. |
| 346 // | 347 // |
| 347 // Release the monitor_ temporarily while we call the start callback. | 348 // Release the monitor_ temporarily while we call the start callback. |
| 348 monitor_.Exit(); | 349 ml.Exit(); |
| 349 status = start_callback_(callback_data_); | 350 status = start_callback_(callback_data_); |
| 350 ASSERT(Isolate::Current() == NULL); | 351 ASSERT(Isolate::Current() == NULL); |
| 351 start_callback_ = NULL; | 352 start_callback_ = NULL; |
| 352 monitor_.Enter(); | 353 ml.Enter(); |
| 353 } | 354 } |
| 354 | 355 |
| 355 // Handle any pending messages for this message handler. | 356 // Handle any pending messages for this message handler. |
| 356 if (status != kShutdown) { | 357 if (status != kShutdown) { |
| 357 status = HandleMessages((status == kOK), true); | 358 status = HandleMessages(&ml, (status == kOK), true); |
| 358 } | 359 } |
| 359 } | 360 } |
| 360 | 361 |
| 361 // The isolate exits when it encounters an error or when it no | 362 // The isolate exits when it encounters an error or when it no |
| 362 // longer has live ports. | 363 // longer has live ports. |
| 363 if (status != kOK || !HasLivePorts()) { | 364 if (status != kOK || !HasLivePorts()) { |
| 364 if (ShouldPauseOnExit(status)) { | 365 if (ShouldPauseOnExit(status)) { |
| 365 if (!is_paused_on_exit()) { | 366 if (!is_paused_on_exit()) { |
| 366 if (FLAG_trace_service_pause_events) { | 367 if (FLAG_trace_service_pause_events) { |
| 367 OS::PrintErr("Isolate %s paused before exiting. " | 368 OS::PrintErr("Isolate %s paused before exiting. " |
| 368 "Use the Observatory to release it.\n", name()); | 369 "Use the Observatory to release it.\n", name()); |
| 369 } | 370 } |
| 370 PausedOnExitLocked(true); | 371 PausedOnExitLocked(true); |
| 371 // More messages may have come in while we released the monitor. | 372 // More messages may have come in while we released the monitor. |
| 372 status = HandleMessages(false, false); | 373 status = HandleMessages(&ml, false, false); |
| 373 } | 374 } |
| 374 if (ShouldPauseOnExit(status)) { | 375 if (ShouldPauseOnExit(status)) { |
| 375 // Still paused. | 376 // Still paused. |
| 376 ASSERT(oob_queue_->IsEmpty()); | 377 ASSERT(oob_queue_->IsEmpty()); |
| 377 task_ = NULL; // No task in queue. | 378 task_ = NULL; // No task in queue. |
| 378 return; | 379 return; |
| 379 } else { | 380 } else { |
| 380 PausedOnExitLocked(false); | 381 PausedOnExitLocked(false); |
| 381 } | 382 } |
| 382 } | 383 } |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 547 | 548 |
| 548 | 549 |
| 549 void MessageHandler::AcquireQueues(AcquiredQueues* acquired_queues) { | 550 void MessageHandler::AcquireQueues(AcquiredQueues* acquired_queues) { |
| 550 ASSERT(acquired_queues != NULL); | 551 ASSERT(acquired_queues != NULL); |
| 551 // No double dipping. | 552 // No double dipping. |
| 552 ASSERT(acquired_queues->handler_ == NULL); | 553 ASSERT(acquired_queues->handler_ == NULL); |
| 553 acquired_queues->Reset(this); | 554 acquired_queues->Reset(this); |
| 554 } | 555 } |
| 555 | 556 |
| 556 } // namespace dart | 557 } // namespace dart |
| OLD | NEW |