session: use msg queue for events
[vpp.git] / src / svm / queue.c
index aef4092..8e18f58 100644 (file)
@@ -26,6 +26,7 @@
 #include <vppinfra/format.h>
 #include <vppinfra/cache.h>
 #include <svm/queue.h>
+#include <vppinfra/time.h>
 #include <signal.h>
 
 /*
@@ -153,26 +154,16 @@ svm_queue_add_nolock (svm_queue_t * q, u8 * elem)
   return 0;
 }
 
-int
+void
 svm_queue_add_raw (svm_queue_t * q, u8 * elem)
 {
   i8 *tailp;
 
-  if (PREDICT_FALSE (q->cursize == q->maxsize))
-    {
-      while (q->cursize == q->maxsize)
-       ;
-    }
-
   tailp = (i8 *) (&q->data[0] + q->elsize * q->tail);
   clib_memcpy (tailp, elem, q->elsize);
 
-  q->tail++;
+  q->tail = (q->tail + 1) % q->maxsize;
   q->cursize++;
-
-  if (q->tail == q->maxsize)
-    q->tail = 0;
-  return 0;
 }
 
 
@@ -299,12 +290,14 @@ svm_queue_add2 (svm_queue_t * q, u8 * elem, u8 * elem2, int nowait)
  * svm_queue_sub
  */
 int
-svm_queue_sub (svm_queue_t * q, u8 * elem, int nowait)
+svm_queue_sub (svm_queue_t * q, u8 * elem, svm_q_conditional_wait_t cond,
+              u32 time)
 {
   i8 *headp;
   int need_broadcast = 0;
+  int rc = 0;
 
-  if (nowait)
+  if (cond == SVM_Q_NOWAIT)
     {
       /* zero on success */
       if (pthread_mutex_trylock (&q->mutex))
@@ -317,14 +310,32 @@ svm_queue_sub (svm_queue_t * q, u8 * elem, int nowait)
 
   if (PREDICT_FALSE (q->cursize == 0))
     {
-      if (nowait)
+      if (cond == SVM_Q_NOWAIT)
        {
          pthread_mutex_unlock (&q->mutex);
          return (-2);
        }
-      while (q->cursize == 0)
+      else if (cond == SVM_Q_TIMEDWAIT)
        {
-         (void) pthread_cond_wait (&q->condvar, &q->mutex);
+         struct timespec ts;
+         ts.tv_sec = unix_time_now () + time;
+         ts.tv_nsec = 0;
+         while (q->cursize == 0 && rc == 0)
+           {
+             rc = pthread_cond_timedwait (&q->condvar, &q->mutex, &ts);
+           }
+         if (rc == ETIMEDOUT)
+           {
+             pthread_mutex_unlock (&q->mutex);
+             return ETIMEDOUT;
+           }
+       }
+      else
+       {
+         while (q->cursize == 0)
+           {
+             (void) pthread_cond_wait (&q->condvar, &q->mutex);
+           }
        }
     }
 
@@ -393,11 +404,9 @@ svm_queue_sub_raw (svm_queue_t * q, u8 * elem)
   headp = (i8 *) (&q->data[0] + q->elsize * q->head);
   clib_memcpy (elem, headp, q->elsize);
 
-  q->head++;
+  q->head = (q->head + 1) % q->maxsize;
   q->cursize--;
 
-  if (q->head == q->maxsize)
-    q->head = 0;
   return 0;
 }