--- utils/rpctrace.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/utils/rpctrace.c b/utils/rpctrace.c index 88b5e38..09911b3 100644 --- a/utils/rpctrace.c +++ b/utils/rpctrace.c @@ -131,6 +131,8 @@ struct traced_info mach_msg_type_name_t type; char *name; /* null or a string describing this */ task_t task; /* The task who has the right. */ + mach_port_seqno_t seqno; /* next RPC to be processed on this port */ + pthread_cond_t sequencer; /* used to sequence RPCs when they are processed out-of-order */ }; /* Each traced port has one receiver info and multiple send wrappers. @@ -366,6 +368,8 @@ new_send_wrapper (struct receiver_info *receive, task_t task, receive->forward, TRACED_INFO (info)->pi.port_right, task2pid (task)); TRACED_INFO (info)->type = MACH_MSG_TYPE_MOVE_SEND; TRACED_INFO (info)->task = task; + TRACED_INFO (info)->seqno = 0; + pthread_cond_init(& TRACED_INFO(info)->sequencer, NULL); info->receive_right = receive; info->next = receive->next; receive->next = info; @@ -396,6 +400,8 @@ new_send_once_wrapper (mach_port_t right, mach_port_t *wrapper_right, task_t tas sizeof *info, &info); assert_perror (err); TRACED_INFO (info)->name = 0; + TRACED_INFO (info)->seqno = 0; + pthread_cond_init(& TRACED_INFO(info)->sequencer, NULL); } info->forward = right; @@ -1207,6 +1213,11 @@ trace_and_forward (mach_msg_header_t *inp, mach_msg_header_t *outp) msgid = msgid_info (inp->msgh_id); + while (inp->msgh_seqno != TRACED_INFO (info)->seqno) + { + pthread_cond_wait (& TRACED_INFO (info)->sequencer, &tracelock); + } + /* Determine message's destination task */ if (INFO_SEND_ONCE(info)) @@ -1370,7 +1381,13 @@ trace_and_forward (mach_msg_header_t *inp, mach_msg_header_t *outp) } } - /* Unlock prior to sending message to avoid deadlocks in the kernel */ + /* Advance our sequence number and signal any other thread waiting + * to process the next message on this port. + */ + TRACED_INFO (info)->seqno = inp->msgh_seqno + 1; + pthread_cond_broadcast (& TRACED_INFO (info)->sequencer); + + /* Unlock prior to resending message to avoid deadlocks in the kernel */ ports_port_deref (info); pthread_mutex_unlock(&tracelock); -- 2.6.4