aboutsummaryrefslogtreecommitdiff
path: root/contrib/ntp/libntp/recvbuff.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ntp/libntp/recvbuff.c')
-rw-r--r--contrib/ntp/libntp/recvbuff.c204
1 files changed, 142 insertions, 62 deletions
diff --git a/contrib/ntp/libntp/recvbuff.c b/contrib/ntp/libntp/recvbuff.c
index 6665686fe068..83a9ee193a3b 100644
--- a/contrib/ntp/libntp/recvbuff.c
+++ b/contrib/ntp/libntp/recvbuff.c
@@ -3,27 +3,27 @@
#endif
#include <stdio.h>
-#include "ntp_machine.h"
-#include "ntp_fp.h"
+
+#include "ntp_assert.h"
#include "ntp_syslog.h"
#include "ntp_stdlib.h"
-#include "ntp_io.h"
+#include "ntp_lists.h"
#include "recvbuff.h"
#include "iosignal.h"
-#include <isc/list.h>
+
/*
* 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 */
+ between replenishments */
-static ISC_LIST(recvbuf_t) full_recv_list; /* Currently used recv buffers */
-static ISC_LIST(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)
@@ -36,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)
{
@@ -64,15 +69,10 @@ lowater_additions(void)
return lowater_adds;
}
-static void
+static inline void
initialise_buffer(recvbuf_t *buff)
{
- memset((char *) buff, 0, sizeof(recvbuf_t));
-
-#if defined SYS_WINNT
- buff->wsabuff.len = RX_BUFF_SIZE;
- buff->wsabuff.buf = (char *) buff->recv_buffer;
-#endif
+ ZERO(*buff);
}
static void
@@ -84,12 +84,20 @@ create_buffers(int nbufs)
abuf = nbufs + buffer_shortfall;
buffer_shortfall = 0;
- bufp = (recvbuf_t *) emalloc(abuf*sizeof(recvbuf_t));
+#ifndef DEBUG
+ bufp = emalloc_zero(abuf * sizeof(*bufp));
+#endif
- for (i = 0; i < abuf; i++)
- {
- memset((char *) bufp, 0, sizeof(recvbuf_t));
- ISC_LIST_APPEND(free_recv_list, bufp, link);
+ for (i = 0; i < abuf; i++) {
+#ifdef DEBUG
+ /*
+ * Allocate each buffer individually so they can be
+ * free()d during ntpd shutdown on DEBUG builds to
+ * keep them out of heap leak reports.
+ */
+ bufp = emalloc_zero(sizeof(*bufp));
+#endif
+ LINK_SLIST(free_recv_list, bufp, link);
bufp++;
free_recvbufs++;
total_recvbufs++;
@@ -104,8 +112,6 @@ init_recvbuff(int nbufs)
/*
* Init buffer free list and stat counters
*/
- ISC_LIST_INIT(full_recv_list);
- ISC_LIST_INIT(free_recv_list);
free_recvbufs = total_recvbufs = 0;
full_recvbufs = lowater_adds = 0;
@@ -115,7 +121,34 @@ init_recvbuff(int nbufs)
InitializeCriticalSection(&RecvLock);
#endif
+#ifdef DEBUG
+ atexit(&uninit_recvbuff);
+#endif
+}
+
+
+#ifdef DEBUG
+static void
+uninit_recvbuff(void)
+{
+ recvbuf_t *rbunlinked;
+
+ for (;;) {
+ UNLINK_FIFO(rbunlinked, full_recv_fifo, link);
+ if (rbunlinked == NULL)
+ break;
+ free(rbunlinked);
+ }
+
+ for (;;) {
+ UNLINK_HEAD_SLIST(rbunlinked, free_recv_list, link);
+ if (rbunlinked == NULL)
+ break;
+ free(rbunlinked);
+ }
}
+#endif /* DEBUG */
+
/*
* freerecvbuf - make a single recvbuf available for reuse
@@ -129,14 +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);
- ISC_LIST_APPEND(free_recv_list, rb, link);
-#if defined SYS_WINNT
- rb->wsabuff.len = RX_BUFF_SIZE;
- rb->wsabuff.buf = (char *) rb->recv_buffer;
-#endif
+ LINK_SLIST(free_recv_list, rb, link);
free_recvbufs++;
UNLOCK();
}
@@ -150,63 +179,66 @@ add_full_recv_buffer(recvbuf_t *rb)
return;
}
LOCK();
- 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 = NULL;
+ recvbuf_t *buffer;
+
LOCK();
- buffer = ISC_LIST_HEAD(free_recv_list);
- if (buffer != NULL)
- {
- ISC_LIST_DEQUEUE(free_recv_list, buffer, link);
+ 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)
{
- recvbuf_t * buffer = get_free_recv_buffer();
- if (buffer == NULL)
- {
+ recvbuf_t *buffer;
+
+ buffer = get_free_recv_buffer();
+ if (NULL == buffer) {
create_buffers(RECV_INC);
buffer = get_free_recv_buffer();
}
+ NTP_ENSURE(buffer != NULL);
return (buffer);
}
#endif
+
recvbuf_t *
get_full_recv_buffer(void)
{
- recvbuf_t *rbuf;
+ recvbuf_t * rbuf;
+
LOCK();
#ifdef HAVE_SIGNALED_IO
/*
* make sure there are free buffers when we
- * wander off to do lengthy paket processing with
+ * wander off to do lengthy packet processing with
* any buffer we grab from the full list.
*
* fixes malloc() interrupted by SIGIO risk
* (Bug 889)
*/
- rbuf = ISC_LIST_HEAD(free_recv_list);
- if (rbuf == NULL || buffer_shortfall > 0) {
+ if (NULL == free_recv_list || buffer_shortfall > 0) {
/*
* try to get us some more buffers
*/
@@ -217,30 +249,78 @@ get_full_recv_buffer(void)
/*
* try to grab a full buffer
*/
- rbuf = ISC_LIST_HEAD(full_recv_list);
+ UNLINK_FIFO(rbuf, full_recv_fifo, link);
if (rbuf != NULL)
- {
- ISC_LIST_DEQUEUE(full_recv_list, rbuf, link);
- --full_recvbufs;
- }
- else
- {
- /*
- * Make sure we reset the full count to 0
- */
- full_recvbufs = 0;
+ full_recvbufs--;
+ UNLOCK();
+
+ 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();
- return (rbuf);
}
+
/*
* 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 */