@@ -26,9 +26,11 @@ void rust_port::deref() {
2626 scoped_lock with (ref_lock);
2727 ref_count--;
2828 if (!ref_count) {
29+ // The port owner is waiting for the port to be detached (if it
30+ // hasn't already been killed)
31+ scoped_lock with (task->lifecycle_lock );
2932 if (task->blocked_on (&detach_cond)) {
30- // The port owner is waiting for the port to be detached
31- task->wakeup (&detach_cond);
33+ task->wakeup_inner (&detach_cond);
3234 }
3335 }
3436}
@@ -64,12 +66,15 @@ void rust_port::send(void *sptr) {
6466 assert (!buffer.is_empty () &&
6567 " rust_chan::transmit with nothing to send." );
6668
67- if (task->blocked_on (this )) {
68- KLOG (kernel, comm, " dequeued in rendezvous_ptr" );
69- buffer.dequeue (task->rendezvous_ptr );
70- task->rendezvous_ptr = 0 ;
71- task->wakeup (this );
72- did_rendezvous = true ;
69+ {
70+ scoped_lock with (task->lifecycle_lock );
71+ if (task->blocked_on (this )) {
72+ KLOG (kernel, comm, " dequeued in rendezvous_ptr" );
73+ buffer.dequeue (task->rendezvous_ptr );
74+ task->rendezvous_ptr = 0 ;
75+ task->wakeup_inner (this );
76+ did_rendezvous = true ;
77+ }
7378 }
7479 }
7580
@@ -78,11 +83,8 @@ void rust_port::send(void *sptr) {
7883 // it may be waiting on a group of ports
7984
8085 rust_port_selector *port_selector = task->get_port_selector ();
81- // This check is not definitive. The port selector will take a lock
82- // and check again whether the task is still blocked.
83- if (task->blocked_on (port_selector)) {
84- port_selector->msg_sent_on (this );
85- }
86+ // The port selector will check if the task is blocked, not us.
87+ port_selector->msg_sent_on (this );
8688 }
8789}
8890
0 commit comments