aboutsummaryrefslogtreecommitdiff
path: root/src/core/msgqueue.c
diff options
context:
space:
mode:
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)