svm: fix producer deadlock in svm_msg_q_wait()
1. When producer invokes svm_msg_q_wait() in svm_msg_q_lock_and_alloc_msg_w_ring(), queue mutex is held by itself.
2. Sometimes, svm msg queue is not full and ring is full, svm_msg_q_wait() do nothing with mutex held, consumer will blocking at svm_msg_q_send_signal().
Type: fix
@@ -497,6 +497,8 @@ svm_msg_q_wait (svm_msg_q_t *mq, svm_msg_q_wait_type_t type)
fn = (type == SVM_MQ_WAIT_EMPTY) ? svm_msg_q_is_empty : svm_msg_q_is_full;
if (mq->q.evtfd == -1)
+ {
+ if (type == SVM_MQ_WAIT_EMPTY)
{
rv = pthread_mutex_lock (&mq->q.shr->mutex);
if (PREDICT_FALSE (rv == EOWNERDEAD))
@@ -504,10 +506,12 @@ svm_msg_q_wait (svm_msg_q_t *mq, svm_msg_q_wait_type_t type)
rv = pthread_mutex_consistent (&mq->q.shr->mutex);
return rv;
}
+ }
while (fn (mq))
pthread_cond_wait (&mq->q.shr->condvar, &mq->q.shr->mutex);
+ if (type == SVM_MQ_WAIT_EMPTY)
pthread_mutex_unlock (&mq->q.shr->mutex);
}
else
