summaryrefslogtreecommitdiffstats
path: root/src/vpp-api/client
diff options
context:
space:
mode:
authorOle Troan <ot@cisco.com>2018-10-08 11:24:22 +0200
committerOle Trøan <otroan@employees.org>2018-10-09 07:23:29 +0000
commitde728ac3c06531f5c16fac65c505f0e63948ebe8 (patch)
tree73bd061fe49825d7cc869698ca75ca2670b478cb /src/vpp-api/client
parent20e6d36bca61dc004131d9be5385c71f8553e1fc (diff)
API: Spurious timeouts from timeout thread.
Change-Id: I1be1101ba4d82688a32b5ae2c39ca5d92dc244b7 Signed-off-by: Ole Troan <ot@cisco.com>
Diffstat (limited to 'src/vpp-api/client')
-rw-r--r--src/vpp-api/client/client.c40
1 files changed, 27 insertions, 13 deletions
diff --git a/src/vpp-api/client/client.c b/src/vpp-api/client/client.c
index 68269bb9b55..a57db289250 100644
--- a/src/vpp-api/client/client.c
+++ b/src/vpp-api/client/client.c
@@ -33,6 +33,9 @@
#include "vppapiclient.h"
+bool timeout_cancelled;
+bool timeout_in_progress;
+
/*
* Asynchronous mode:
* Client registers a callback. All messages are sent to the callback.
@@ -234,27 +237,31 @@ vac_timeout_thread_fn (void *arg)
api_main_t *am = &api_main;
struct timespec ts;
struct timeval tv;
- u16 timeout;
int rv;
while (pm->timeout_loop)
{
/* Wait for poke */
pthread_mutex_lock(&pm->timeout_lock);
- pthread_cond_wait (&pm->timeout_cv, &pm->timeout_lock);
- timeout = read_timeout;
+ while (!timeout_in_progress)
+ pthread_cond_wait (&pm->timeout_cv, &pm->timeout_lock);
+
+ /* Starting timer */
gettimeofday(&tv, NULL);
- ts.tv_sec = tv.tv_sec + timeout;
+ ts.tv_sec = tv.tv_sec + read_timeout;
ts.tv_nsec = 0;
- rv = pthread_cond_timedwait (&pm->timeout_cancel_cv,
- &pm->timeout_lock, &ts);
- pthread_mutex_unlock(&pm->timeout_lock);
- if (rv == ETIMEDOUT && !timeout_thread_cancelled)
- {
+
+ if (!timeout_cancelled) {
+ rv = pthread_cond_timedwait (&pm->timeout_cancel_cv,
+ &pm->timeout_lock, &ts);
+ if (rv == ETIMEDOUT && !timeout_thread_cancelled) {
ep = vl_msg_api_alloc (sizeof (*ep));
ep->_vl_msg_id = ntohs(VL_API_MEMCLNT_READ_TIMEOUT);
vl_msg_api_send_shmem(am->vl_input_queue, (u8 *)&ep);
}
+ }
+
+ pthread_mutex_unlock(&pm->timeout_lock);
}
pthread_exit(0);
}
@@ -353,13 +360,14 @@ vac_connect (char * name, char * chroot_prefix, vac_callback_t cb,
return (0);
}
-
static void
set_timeout (unsigned short timeout)
{
vac_main_t *pm = &vac_main;
pthread_mutex_lock(&pm->timeout_lock);
read_timeout = timeout;
+ timeout_in_progress = true;
+ timeout_cancelled = false;
pthread_cond_signal(&pm->timeout_cv);
pthread_mutex_unlock(&pm->timeout_lock);
}
@@ -369,6 +377,8 @@ unset_timeout (void)
{
vac_main_t *pm = &vac_main;
pthread_mutex_lock(&pm->timeout_lock);
+ timeout_in_progress = false;
+ timeout_cancelled = true;
pthread_cond_signal(&pm->timeout_cancel_cv);
pthread_mutex_unlock(&pm->timeout_lock);
}
@@ -453,7 +463,7 @@ vac_read (char **p, int *l, u16 timeout)
switch (msg_id) {
case VL_API_RX_THREAD_EXIT:
vl_msg_api_free((void *) msg);
- return -1;
+ goto error;
case VL_API_MEMCLNT_RX_THREAD_SUSPEND:
goto error;
case VL_API_MEMCLNT_READ_TIMEOUT:
@@ -484,15 +494,19 @@ vac_read (char **p, int *l, u16 timeout)
}
*p = (char *)msg;
- /* Let timeout notification thread know we're done */
- unset_timeout();
} else {
fprintf(stderr, "Read failed with %d\n", rv);
}
+ /* Let timeout notification thread know we're done */
+ if (timeout)
+ unset_timeout();
+
return (rv);
error:
+ if (timeout)
+ unset_timeout();
vl_msg_api_free((void *) msg);
/* Client might forget to resume RX thread on failure */
vac_rx_resume ();
'>106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160