aboutsummaryrefslogtreecommitdiff
path: root/src/rt/rust_kernel.cpp
diff options
context:
space:
mode:
authorMichael Bebenita <[email protected]>2010-09-07 23:37:51 -0700
committerMichael Bebenita <[email protected]>2010-09-07 23:37:51 -0700
commit7f6d8b95bd3340ea5fa32874243dac036208105b (patch)
tree7010caf355578adc06a0919df97b0418683ba41f /src/rt/rust_kernel.cpp
parentLots of design changes around proxies and message passing. Made it so that do... (diff)
downloadrust-7f6d8b95bd3340ea5fa32874243dac036208105b.tar.xz
rust-7f6d8b95bd3340ea5fa32874243dac036208105b.zip
Fixed race in the rust kernel.
Diffstat (limited to 'src/rt/rust_kernel.cpp')
-rw-r--r--src/rt/rust_kernel.cpp47
1 files changed, 30 insertions, 17 deletions
diff --git a/src/rt/rust_kernel.cpp b/src/rt/rust_kernel.cpp
index 9ea1f2eb..910e33c6 100644
--- a/src/rt/rust_kernel.cpp
+++ b/src/rt/rust_kernel.cpp
@@ -129,20 +129,25 @@ rust_kernel::log(uint32_t type_bits, char const *fmt, ...) {
}
void
-rust_kernel::start_kernel_loop() {
- while (_interrupt_kernel_loop == false) {
- message_queues.global.lock();
- for (size_t i = 0; i < message_queues.length(); i++) {
- rust_message_queue *queue = message_queues[i];
- if (queue->is_associated() == false) {
- rust_message *message = NULL;
- while (queue->dequeue(&message)) {
- message->kernel_process();
- delete message;
- }
+rust_kernel::pump_message_queues() {
+ message_queues.global.lock();
+ for (size_t i = 0; i < message_queues.length(); i++) {
+ rust_message_queue *queue = message_queues[i];
+ if (queue->is_associated() == false) {
+ rust_message *message = NULL;
+ while (queue->dequeue(&message)) {
+ message->kernel_process();
+ delete message;
}
}
- message_queues.global.unlock();
+ }
+ message_queues.global.unlock();
+}
+
+void
+rust_kernel::start_kernel_loop() {
+ while (_interrupt_kernel_loop == false) {
+ pump_message_queues();
}
}
@@ -153,16 +158,24 @@ rust_kernel::run() {
log(rust_log::KERN, "finished kernel loop");
}
+void
+rust_kernel::terminate_kernel_loop() {
+ _interrupt_kernel_loop = true;
+ join();
+}
+
rust_kernel::~rust_kernel() {
K(_srv, domains.length() == 0,
"Kernel has %d live domain(s), join all domains before killing "
"the kernel.", domains.length());
- // If the kernel loop is running, interrupt it, join and exit.
- if (is_running()) {
- _interrupt_kernel_loop = true;
- join();
- }
+ terminate_kernel_loop();
+
+ // It's possible that the message pump misses some messages because
+ // of races, so pump any remaining messages here. By now all domain
+ // threads should have been joined, so we shouldn't miss any more
+ // messages.
+ pump_message_queues();
free_handles(_task_handles);
free_handles(_port_handles);