summaryrefslogtreecommitdiff
path: root/src/core/msgqueue.c
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2016-12-28 22:52:53 -0800
committerGarrett D'Amore <garrett@damore.org>2016-12-28 22:52:53 -0800
commite8c4e9ebe5d8c2565c79bb906e8298013988ceb0 (patch)
tree392fb1785a1c795cc4313425cc426119c8848a18 /src/core/msgqueue.c
parent3e7507f5908cda4b669bc57293e8395164fcc11a (diff)
downloadnng-e8c4e9ebe5d8c2565c79bb906e8298013988ceb0.tar.gz
nng-e8c4e9ebe5d8c2565c79bb906e8298013988ceb0.tar.bz2
nng-e8c4e9ebe5d8c2565c79bb906e8298013988ceb0.zip
Implement msgqueue_putback.
This function is called when we wish to return a message to the queue after examining it. It can also be used by the resender in the REQ protocol. Critically it does not disrupt the ordering of other messages. This is a non-blocking operation.
Diffstat (limited to 'src/core/msgqueue.c')
-rw-r--r--src/core/msgqueue.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/core/msgqueue.c b/src/core/msgqueue.c
index 41127c50..3af4e081 100644
--- a/src/core/msgqueue.c
+++ b/src/core/msgqueue.c
@@ -198,6 +198,41 @@ nni_msgqueue_put_impl(nni_msgqueue *mq, nni_msg *msg,
}
+// nni_msgqueue_putback will attempt to put a single message back
+// to the head of the queue. It never blocks. Message queues always
+// have room for at least one putback.
+int
+nni_msgqueue_putback(nni_msgqueue *mq, nni_msg *msg)
+{
+ nni_mutex_enter(&mq->mq_lock);
+
+ // if closed, we don't put more... this check is first!
+ if (mq->mq_closed) {
+ nni_mutex_exit(&mq->mq_lock);
+ return (NNG_ECLOSED);
+ }
+
+ // room in the queue?
+ if (mq->mq_len >= mq->mq_cap) {
+ nni_mutex_exit(&mq->mq_lock);
+ return (NNG_EAGAIN);
+ }
+
+ // Subtract one from the get index, possibly wrapping.
+ mq->mq_get--;
+ if (mq->mq_get == 0) {
+ mq->mq_get = mq->mq_cap;
+ }
+ mq->mq_msgs[mq->mq_get] = msg;
+ mq->mq_len++;
+ if (mq->mq_rwait) {
+ nni_cond_broadcast(&mq->mq_readable);
+ }
+ nni_mutex_exit(&mq->mq_lock);
+ return (0);
+}
+
+
static int
nni_msgqueue_get_impl(nni_msgqueue *mq, nni_msg **msgp,
nni_time expire, nni_signal *signal)