mqueues: Fix deadlock situation.
authorStathis Kamperis <beket@dragonflybsd.org>
Sat, 16 Jan 2010 21:18:37 +0000 (23:18 +0200)
committerStathis Kamperis <beket@dragonflybsd.org>
Sat, 16 Jan 2010 21:23:54 +0000 (23:23 +0200)
tsleep() doesn't release the per-mqueue exclusive lockmgr lock before sleeping.
We need lksleep() instead.

Reported-by: swildner@
sys/kern/sys_mqueue.c

index 2152935..5067b6e 100644 (file)
@@ -629,7 +629,7 @@ mq_receive1(struct lwp *l, mqd_t mqdes, void *msg_ptr, size_t msg_len,
                 * While doing this, notification should not be sent.
                 */
                mqattr->mq_flags |= MQ_RECEIVE;
-               error = tsleep(&mq->mq_send_cv, PCATCH, "mqsend", t);
+               error = lksleep(&mq->mq_send_cv, &mq->mq_mtx, PCATCH, "mqsend", t);
                mqattr->mq_flags &= ~MQ_RECEIVE;
                if (error || (mqattr->mq_flags & MQ_UNLINK)) {
                        error = (error == EWOULDBLOCK) ? ETIMEDOUT : EINTR;
@@ -811,7 +811,7 @@ mq_send1(struct lwp *l, mqd_t mqdes, const char *msg_ptr, size_t msg_len,
                } else
                        t = 0;
                /* Block until queue becomes available */
-               error = tsleep(&mq->mq_recv_cv, PCATCH, "mqrecv", t);
+               error = lksleep(&mq->mq_recv_cv, &mq->mq_mtx, PCATCH, "mqrecv", t);
                if (error || (mqattr->mq_flags & MQ_UNLINK)) {
                        error = (error == EWOULDBLOCK) ? ETIMEDOUT : error;
                        goto error;