diff options
Diffstat (limited to 'libntp/recvbuff.c')
-rw-r--r-- | libntp/recvbuff.c | 150 |
1 files changed, 103 insertions, 47 deletions
diff --git a/libntp/recvbuff.c b/libntp/recvbuff.c index 9a7d6caf4333..83a9ee193a3b 100644 --- a/libntp/recvbuff.c +++ b/libntp/recvbuff.c @@ -3,34 +3,27 @@ #endif #include <stdio.h> -#include "ntp_machine.h" + #include "ntp_assert.h" -#include "ntp_fp.h" #include "ntp_syslog.h" #include "ntp_stdlib.h" -#include "ntp_io.h" #include "ntp_lists.h" #include "recvbuff.h" #include "iosignal.h" - -#ifdef DEBUG -static void uninit_recvbuff(void); -#endif - /* * Memory allocation */ -static u_long volatile full_recvbufs; /* number of recvbufs on fulllist */ -static u_long volatile free_recvbufs; /* number of recvbufs on freelist */ +static u_long volatile full_recvbufs; /* recvbufs on full_recv_fifo */ +static u_long volatile free_recvbufs; /* recvbufs on free_recv_list */ static u_long volatile total_recvbufs; /* total recvbufs currently in use */ static u_long volatile lowater_adds; /* number of times we have added memory */ static u_long volatile buffer_shortfall;/* number of missed free receive buffers between replenishments */ -static ISC_LIST(recvbuf_t) full_recv_list; /* Currently used recv buffers */ -static recvbuf_t * free_recv_list; /* Currently unused buffers */ +static DECL_FIFO_ANCHOR(recvbuf_t) full_recv_fifo; +static recvbuf_t * free_recv_list; #if defined(SYS_WINNT) @@ -43,10 +36,15 @@ static CRITICAL_SECTION RecvLock; # define LOCK() EnterCriticalSection(&RecvLock) # define UNLOCK() LeaveCriticalSection(&RecvLock) #else -# define LOCK() -# define UNLOCK() +# define LOCK() do {} while (FALSE) +# define UNLOCK() do {} while (FALSE) #endif +#ifdef DEBUG +static void uninit_recvbuff(void); +#endif + + u_long free_recvbuffs (void) { @@ -74,7 +72,7 @@ lowater_additions(void) static inline void initialise_buffer(recvbuf_t *buff) { - memset(buff, 0, sizeof(*buff)); + ZERO(*buff); } static void @@ -87,7 +85,7 @@ create_buffers(int nbufs) buffer_shortfall = 0; #ifndef DEBUG - bufp = emalloc(abuf * sizeof(*bufp)); + bufp = emalloc_zero(abuf * sizeof(*bufp)); #endif for (i = 0; i < abuf; i++) { @@ -97,10 +95,9 @@ create_buffers(int nbufs) * free()d during ntpd shutdown on DEBUG builds to * keep them out of heap leak reports. */ - bufp = emalloc(sizeof(*bufp)); + bufp = emalloc_zero(sizeof(*bufp)); #endif - memset(bufp, 0, sizeof(*bufp)); - LINK_SLIST(free_recv_list, bufp, link.next); + LINK_SLIST(free_recv_list, bufp, link); bufp++; free_recvbufs++; total_recvbufs++; @@ -115,7 +112,6 @@ init_recvbuff(int nbufs) /* * Init buffer free list and stat counters */ - ISC_LIST_INIT(full_recv_list); free_recvbufs = total_recvbufs = 0; full_recvbufs = lowater_adds = 0; @@ -137,16 +133,19 @@ uninit_recvbuff(void) { recvbuf_t *rbunlinked; - while ((rbunlinked = ISC_LIST_HEAD(full_recv_list)) != NULL) { - ISC_LIST_DEQUEUE_TYPE(full_recv_list, rbunlinked, link, recvbuf_t); + for (;;) { + UNLINK_FIFO(rbunlinked, full_recv_fifo, link); + if (rbunlinked == NULL) + break; free(rbunlinked); } - do { - UNLINK_HEAD_SLIST(rbunlinked, free_recv_list, link.next); - if (rbunlinked != NULL) - free(rbunlinked); - } while (rbunlinked != NULL); + for (;;) { + UNLINK_HEAD_SLIST(rbunlinked, free_recv_list, link); + if (rbunlinked == NULL) + break; + free(rbunlinked); + } } #endif /* DEBUG */ @@ -163,10 +162,10 @@ freerecvbuf(recvbuf_t *rb) } LOCK(); - (rb->used)--; + rb->used--; if (rb->used != 0) msyslog(LOG_ERR, "******** freerecvbuff non-zero usage: %d *******", rb->used); - LINK_SLIST(free_recv_list, rb, link.next); + LINK_SLIST(free_recv_list, rb, link); free_recvbufs++; UNLOCK(); } @@ -180,29 +179,32 @@ add_full_recv_buffer(recvbuf_t *rb) return; } LOCK(); - ISC_LINK_INIT(rb, link); - ISC_LIST_APPEND(full_recv_list, rb, link); + LINK_FIFO(full_recv_fifo, rb, link); full_recvbufs++; UNLOCK(); } + recvbuf_t * get_free_recv_buffer(void) { recvbuf_t *buffer; LOCK(); - UNLINK_HEAD_SLIST(buffer, free_recv_list, link.next); + UNLINK_HEAD_SLIST(buffer, free_recv_list, link); if (buffer != NULL) { free_recvbufs--; initialise_buffer(buffer); - (buffer->used)++; - } else + buffer->used++; + } else { buffer_shortfall++; + } UNLOCK(); - return (buffer); + + return buffer; } + #ifdef HAVE_IO_COMPLETION_PORT recvbuf_t * get_free_recv_buffer_alloc(void) @@ -219,10 +221,12 @@ get_free_recv_buffer_alloc(void) } #endif + recvbuf_t * get_full_recv_buffer(void) { - recvbuf_t *rbuf; + recvbuf_t * rbuf; + LOCK(); #ifdef HAVE_SIGNALED_IO @@ -245,26 +249,78 @@ get_full_recv_buffer(void) /* * try to grab a full buffer */ - rbuf = ISC_LIST_HEAD(full_recv_list); - if (rbuf != NULL) { - ISC_LIST_DEQUEUE_TYPE(full_recv_list, rbuf, link, recvbuf_t); - --full_recvbufs; - } else - /* - * Make sure we reset the full count to 0 - */ - full_recvbufs = 0; + UNLINK_FIFO(rbuf, full_recv_fifo, link); + if (rbuf != NULL) + full_recvbufs--; UNLOCK(); - return (rbuf); + + return rbuf; } + +/* + * purge_recv_buffers_for_fd() - purges any previously-received input + * from a given file descriptor. + */ +void +purge_recv_buffers_for_fd( + SOCKET fd + ) +{ + recvbuf_t *rbufp; + recvbuf_t *next; + recvbuf_t *punlinked; + + LOCK(); + + for (rbufp = HEAD_FIFO(full_recv_fifo); + rbufp != NULL; + rbufp = next) { + next = rbufp->link; + if (rbufp->fd == fd) { + UNLINK_MID_FIFO(punlinked, full_recv_fifo, + rbufp, link, recvbuf_t); + INSIST(punlinked == rbufp); + full_recvbufs--; + freerecvbuf(rbufp); + } + } + + UNLOCK(); +} + + /* * Checks to see if there are buffers to process */ isc_boolean_t has_full_recv_buffer(void) { - if (ISC_LIST_HEAD(full_recv_list) != NULL) + if (HEAD_FIFO(full_recv_fifo) != NULL) return (ISC_TRUE); else return (ISC_FALSE); } + + +#ifdef NTP_DEBUG_LISTS_H +void +check_gen_fifo_consistency(void *fifo) +{ + gen_fifo *pf; + gen_node *pthis; + gen_node **pptail; + + pf = fifo; + REQUIRE((NULL == pf->phead && NULL == pf->pptail) || + (NULL != pf->phead && NULL != pf->pptail)); + + pptail = &pf->phead; + for (pthis = pf->phead; + pthis != NULL; + pthis = pthis->link) + if (NULL != pthis->link) + pptail = &pthis->link; + + REQUIRE(NULL == pf->pptail || pptail == pf->pptail); +} +#endif /* NTP_DEBUG_LISTS_H */ |