about summary refs log tree commit diff
path: root/src/boot
diff options
context:
space:
mode:
authorMichael Bebenita <mbebenita@mozilla.com>2010-08-09 08:15:34 -0700
committerMichael Bebenita <mbebenita@mozilla.com>2010-08-09 08:15:34 -0700
commit97d6342bf08e55f8d2b4f8df5c4b5a099df0191c (patch)
treebfed15fefbc032deba1c34908f25c1562d88aa6b /src/boot
parent5917ca35190b526b65b4d26ad0b98024ce9e0b09 (diff)
Synthesize a flush_chan upcall right before a channel's ref_count drops to zero. This should only happen in the Rust code and not in the drop glue, or on the unwind path. This change allows the task owning the channel to block on a flush and delete its own channel. This change also cleans up some code around rust_port and rust_chan.
Diffstat (limited to 'src/boot')
-rw-r--r--src/boot/me/trans.ml20
1 files changed, 20 insertions, 0 deletions
diff --git a/src/boot/me/trans.ml b/src/boot/me/trans.ml
index b708bb268ff..97dce2b2c58 100644
--- a/src/boot/me/trans.ml
+++ b/src/boot/me/trans.ml
@@ -2932,6 +2932,7 @@ let trans_visitor
       (slot:Ast.slot)
       (curr_iso:Ast.ty_iso option)
       : unit =
+      check_and_flush_chan cell slot;
       drop_slot (get_ty_params_of_current_frame()) cell slot curr_iso
 
   and drop_ty_in_current_frame
@@ -4188,6 +4189,25 @@ let trans_visitor
     let last_jumps = Array.map trans_arm at.Ast.alt_tag_arms in
       Array.iter patch last_jumps
 
+  (* If we're about to drop a channel, synthesize an upcall_flush_chan.
+   * TODO: This should rather appear in a chan dtor when chans become
+   * objects. *)
+  and check_and_flush_chan
+    (cell:Il.cell)
+    (slot:Ast.slot)
+      : unit =
+      let ty = strip_mutable_or_constrained_ty (slot_ty slot) in
+      match simplified_ty ty with
+          Ast.TY_chan _ ->
+                annotate "check_and_flush_chan, flush_chan";
+                let rc = box_rc_cell cell in
+                  emit (Il.cmp (Il.Cell rc) one);
+                let jump = mark () in
+                  emit (Il.jmp Il.JNE Il.CodeNone);
+                  trans_void_upcall "upcall_flush_chan" [| Il.Cell cell |];
+                  patch jump;
+        | _ -> ()
+
   and drop_slots_at_curr_stmt _ : unit =
     let stmt = Stack.top curr_stmt in
       match htab_search cx.ctxt_post_stmt_slot_drops stmt with