From 7f1524669755d7a6e6cd1c3fb80084df273f3dc1 Mon Sep 17 00:00:00 2001 From: Thomas Markwalder Date: Thu, 23 Jan 2020 16:21:52 -0500 Subject: [#76] Initial implemention to dhcpctl_timed_wait_for_completion common/conflex.c includes/dhctoken.h dhcpctl/omshell.c Added support for "disconnect" dhcpctl/cltest.2 - new file that exercizes timed waits and disconnect dhcpctl/Makefile.am.in Added cltest2.c dhcpctl/dhcpctl.* dhcpctl_timed_wait_for_completion() - new function dhcpctl_disconnect() - new function Added debug logging omapip/dispatch.c Added protocol logging omapi_wait_for_completion() Fixed dangling waiter reference omapi_one_dispatch() Added logic to skip emit writefds from select list omapip/support.c Changed annoying DEBUG logs to DEBUG_PROTOCOL --- omapip/connection.c | 2 +- omapip/dispatch.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++---- omapip/support.c | 4 +-- 3 files changed, 71 insertions(+), 8 deletions(-) (limited to 'omapip') diff --git a/omapip/connection.c b/omapip/connection.c index 07b60a09..f1207757 100644 --- a/omapip/connection.c +++ b/omapip/connection.c @@ -461,7 +461,7 @@ isc_result_t omapi_disconnect (omapi_object_t *h, omapi_connection_object_t *c; #ifdef DEBUG_PROTOCOL - log_debug ("omapi_disconnect(%s)", force ? "force" : ""); + log_debug ("omapi_disconnect(force=%d)", force); #endif c = (omapi_connection_object_t *)h; diff --git a/omapip/dispatch.c b/omapip/dispatch.c index 426455ef..c730094c 100644 --- a/omapip/dispatch.c +++ b/omapip/dispatch.c @@ -413,13 +413,26 @@ isc_result_t omapi_unregister_io_object (omapi_object_t *h) isc_result_t omapi_dispatch (struct timeval *t) { +#ifdef DEBUG_PROTOCOL + log_debug("omapi_dispatch()"); +#endif return omapi_wait_for_completion ((omapi_object_t *)&omapi_io_states, + t); } isc_result_t omapi_wait_for_completion (omapi_object_t *object, struct timeval *t) { +#ifdef DEBUG_PROTOCOL + if (t) { + log_debug ("omapi_wait_for_completion(%u.%u secs)", + (unsigned int)(t->tv_sec), + (unsigned int)(t->tv_usec)); + } else { + log_debug ("omapi_wait_for_completion(no timeout)"); + } +#endif isc_result_t status; omapi_waiter_object_t *waiter; omapi_object_t *inner; @@ -453,10 +466,17 @@ isc_result_t omapi_wait_for_completion (omapi_object_t *object, do { status = omapi_one_dispatch ((omapi_object_t *)waiter, t); - if (status != ISC_R_SUCCESS) - return status; + if (status != ISC_R_SUCCESS) { +#ifdef DEBUG_PROTOCOL + log_debug ("- call to omapi_one_dispatch failed: %s", + isc_result_totext (status)); +#endif + /* Break out on failure, to ensure we free up the waiter(s) */ + break; + } } while (!waiter || !waiter -> ready); + if (waiter -> outer) { if (waiter -> outer -> inner) { omapi_object_dereference (&waiter -> outer -> inner, @@ -471,7 +491,12 @@ isc_result_t omapi_wait_for_completion (omapi_object_t *object, if (waiter -> inner) omapi_object_dereference (&waiter -> inner, MDL); - status = waiter -> waitstatus; + if (status == ISC_R_SUCCESS) { + /* If the invocation worked, return the server's + * execution status */ + status = waiter -> waitstatus; + } + omapi_waiter_dereference (&waiter, MDL); return status; } @@ -479,6 +504,9 @@ isc_result_t omapi_wait_for_completion (omapi_object_t *object, isc_result_t omapi_one_dispatch (omapi_object_t *wo, struct timeval *t) { +#ifdef DEBUG_PROTOCOL + log_debug ("omapi_one_dispatch()"); +#endif fd_set r, w, x, rr, ww, xx; int max = 0; int count; @@ -549,6 +577,25 @@ isc_result_t omapi_one_dispatch (omapi_object_t *wo, /* Same deal for write fdets. */ if (io -> writefd && io -> inner && (desc = (*(io -> writefd)) (io -> inner)) >= 0) { + /* This block avoids adding writefds that are already connected + * but that do not have data waiting to write. This avoids + * select() calls dropping immediately simply because the + * the writefd is ready to write. Without this synchronous + * waiting becomes CPU intensive polling */ + if (io->inner && io->inner->type == omapi_type_connection) { + omapi_connection_object_t* c; + c = (omapi_connection_object_t *)(io->inner); + if (c->state == omapi_connection_connected && c->out_bytes == 0) { + /* We are already connected and have no data waiting to + * be written, so we avoid registering the fd. */ +#ifdef DEBUG_PROTOCOL + log_debug ("--- Connected, nothing to write, skip writefd\n"); +#endif + continue; + } + } + + FD_SET (desc, &w); if (desc > max) max = desc; @@ -571,6 +618,14 @@ isc_result_t omapi_one_dispatch (omapi_object_t *wo, r = rr; w = ww; x = xx; + +#ifdef DEBUG_PROTOCOL + if (t) { + log_debug (" calling select with timout: %u.%u secs", + (unsigned int)(to.tv_sec), + (unsigned int)(to.tv_usec)); + } +#endif count = select(max + 1, &r, &w, &x, t ? &to : NULL); } @@ -681,16 +736,18 @@ isc_result_t omapi_one_dispatch (omapi_object_t *wo, see if we got input on that socket. */ if (io -> readfd && (desc = (*(io -> readfd)) (tmp)) >= 0) { - if (FD_ISSET (desc, &r)) + if (FD_ISSET (desc, &r)) { ((*(io -> reader)) (tmp)); + } } /* Same deal for write descriptors. */ if (io -> writefd && (desc = (*(io -> writefd)) (tmp)) >= 0) { - if (FD_ISSET (desc, &w)) + if (FD_ISSET (desc, &w)) { ((*(io -> writer)) (tmp)); + } } omapi_object_dereference (&tmp, MDL); } @@ -837,6 +894,9 @@ isc_result_t omapi_io_destroy (omapi_object_t *h, const char *file, int line) isc_result_t omapi_io_signal_handler (omapi_object_t *h, const char *name, va_list ap) { +#ifdef DEBUG_PROTOCOL + log_debug ("omapi_io_signal_handler(%s)", name); +#endif if (h -> type != omapi_type_io_object) return DHCP_R_INVALIDARG; @@ -864,6 +924,9 @@ isc_result_t omapi_waiter_signal_handler (omapi_object_t *h, { omapi_waiter_object_t *waiter; +#ifdef DEBUG_PROTOCOL + log_debug ("omapi_waiter_signal_handler(%s)", name); +#endif if (h -> type != omapi_type_waiter) return DHCP_R_INVALIDARG; diff --git a/omapip/support.c b/omapip/support.c index f3791de0..92000a17 100644 --- a/omapip/support.c +++ b/omapip/support.c @@ -308,7 +308,7 @@ isc_result_t omapi_set_value (omapi_object_t *h, omapi_object_t *outer; isc_result_t status; -#if defined (DEBUG) +#if defined (DEBUG_PROTOCOL) if (!value) { log_info ("omapi_set_value (%.*s, NULL)", (int)name -> len, name -> value); @@ -343,7 +343,7 @@ isc_result_t omapi_set_value (omapi_object_t *h, id, name, value); else status = ISC_R_NOTFOUND; -#if defined (DEBUG) +#if defined (DEBUG_PROTOCOL) log_info (" ==> %s", isc_result_totext (status)); #endif return status; -- cgit v1.2.1