summaryrefslogtreecommitdiff
path: root/ipc/mach_msg.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/mach_msg.c')
-rw-r--r--ipc/mach_msg.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/ipc/mach_msg.c b/ipc/mach_msg.c
index 371d725..6bd0d29 100644
--- a/ipc/mach_msg.c
+++ b/ipc/mach_msg.c
@@ -742,6 +742,8 @@ mach_msg_trap(
* and not abort when we try to lock dest_mqueue.
*/
+ assert(have_ip_lock(dest_port));
+ assert(have_imq_lock(rcv_mqueue));
assert(ip_active(dest_port));
assert(dest_port->ip_receiver != ipc_space_kernel);
assert((dest_port->ip_msgcount < dest_port->ip_qlimit) ||
@@ -791,19 +793,30 @@ mach_msg_trap(
self->ith_object = rcv_object;
self->ith_mqueue = rcv_mqueue;
+ ip_lock_surrender(dest_port);
+ imq_lock_surrender(rcv_mqueue);
+ imq_lock_surrender(dest_mqueue);
+
if ((receiver->swap_func == (void (*)()) mach_msg_continue) &&
thread_handoff(self, mach_msg_continue, receiver)) {
assert(current_thread() == receiver);
+ ip_lock_steal(dest_port);
+ imq_lock_steal(rcv_mqueue);
+ imq_lock_steal(dest_mqueue);
/*
* We can use the optimized receive code,
* because the receiver is using no options.
*/
+
} else if ((receiver->swap_func ==
(void (*)()) exception_raise_continue) &&
thread_handoff(self, mach_msg_continue, receiver)) {
counter(c_mach_msg_trap_block_exc++);
assert(current_thread() == receiver);
+ ip_lock_steal(dest_port);
+ imq_lock_steal(rcv_mqueue);
+ imq_lock_steal(dest_mqueue);
/*
* We are a reply message coming back through
@@ -830,6 +843,9 @@ mach_msg_trap(
} else if ((send_size <= receiver->ith_msize) &&
thread_handoff(self, mach_msg_continue, receiver)) {
assert(current_thread() == receiver);
+ ip_lock_steal(dest_port);
+ imq_lock_steal(rcv_mqueue);
+ imq_lock_steal(dest_mqueue);
if ((receiver->swap_func ==
(void (*)()) mach_msg_receive_continue) &&
@@ -875,6 +891,9 @@ mach_msg_trap(
* The receiver can't accept the message,
* or we can't switch to the receiver.
*/
+ ip_lock_steal(dest_port);
+ imq_lock_steal(rcv_mqueue);
+ imq_lock_steal(dest_mqueue);
imq_unlock(dest_mqueue);
goto abort_send_receive;