7 #include "ntp_assert.h"
8 #include "ntp_syslog.h"
9 #include "ntp_stdlib.h"
10 #include "ntp_lists.h"
18 static u_long volatile full_recvbufs; /* recvbufs on full_recv_fifo */
19 static u_long volatile free_recvbufs; /* recvbufs on free_recv_list */
20 static u_long volatile total_recvbufs; /* total recvbufs currently in use */
21 static u_long volatile lowater_adds; /* number of times we have added memory */
22 static u_long volatile buffer_shortfall;/* number of missed free receive buffers
23 between replenishments */
25 static DECL_FIFO_ANCHOR(recvbuf_t) full_recv_fifo;
26 static recvbuf_t * free_recv_list;
28 #if defined(SYS_WINNT)
31 * For Windows we need to set up a lock to manipulate the
32 * recv buffers to prevent corruption. We keep it lock for as
33 * short a time as possible
35 static CRITICAL_SECTION RecvLock;
36 # define LOCK() EnterCriticalSection(&RecvLock)
37 # define UNLOCK() LeaveCriticalSection(&RecvLock)
39 # define LOCK() do {} while (FALSE)
40 # define UNLOCK() do {} while (FALSE)
44 static void uninit_recvbuff(void);
61 total_recvbuffs (void)
63 return total_recvbufs;
67 lowater_additions(void)
73 initialise_buffer(recvbuf_t *buff)
79 create_buffers(int nbufs)
81 register recvbuf_t *bufp;
84 abuf = nbufs + buffer_shortfall;
88 bufp = emalloc_zero(abuf * sizeof(*bufp));
91 for (i = 0; i < abuf; i++) {
94 * Allocate each buffer individually so they can be
95 * free()d during ntpd shutdown on DEBUG builds to
96 * keep them out of heap leak reports.
98 bufp = emalloc_zero(sizeof(*bufp));
100 LINK_SLIST(free_recv_list, bufp, link);
109 init_recvbuff(int nbufs)
113 * Init buffer free list and stat counters
115 free_recvbufs = total_recvbufs = 0;
116 full_recvbufs = lowater_adds = 0;
118 create_buffers(nbufs);
120 #if defined(SYS_WINNT)
121 InitializeCriticalSection(&RecvLock);
125 atexit(&uninit_recvbuff);
132 uninit_recvbuff(void)
134 recvbuf_t *rbunlinked;
137 UNLINK_FIFO(rbunlinked, full_recv_fifo, link);
138 if (rbunlinked == NULL)
144 UNLINK_HEAD_SLIST(rbunlinked, free_recv_list, link);
145 if (rbunlinked == NULL)
154 * freerecvbuf - make a single recvbuf available for reuse
157 freerecvbuf(recvbuf_t *rb)
163 msyslog(LOG_ERR, "******** freerecvbuff non-zero usage: %d *******", rb->used);
164 LINK_SLIST(free_recv_list, rb, link);
172 add_full_recv_buffer(recvbuf_t *rb)
175 msyslog(LOG_ERR, "add_full_recv_buffer received NULL buffer");
179 LINK_FIFO(full_recv_fifo, rb, link);
186 get_free_recv_buffer(void)
191 UNLINK_HEAD_SLIST(buffer, free_recv_list, link);
192 if (buffer != NULL) {
194 initialise_buffer(buffer);
205 #ifdef HAVE_IO_COMPLETION_PORT
207 get_free_recv_buffer_alloc(void)
211 buffer = get_free_recv_buffer();
212 if (NULL == buffer) {
213 create_buffers(RECV_INC);
214 buffer = get_free_recv_buffer();
216 ENSURE(buffer != NULL);
223 get_full_recv_buffer(void)
229 #ifdef HAVE_SIGNALED_IO
231 * make sure there are free buffers when we
232 * wander off to do lengthy packet processing with
233 * any buffer we grab from the full list.
235 * fixes malloc() interrupted by SIGIO risk
238 if (NULL == free_recv_list || buffer_shortfall > 0) {
240 * try to get us some more buffers
242 create_buffers(RECV_INC);
247 * try to grab a full buffer
249 UNLINK_FIFO(rbuf, full_recv_fifo, link);
259 * purge_recv_buffers_for_fd() - purges any previously-received input
260 * from a given file descriptor.
263 purge_recv_buffers_for_fd(
269 recvbuf_t *punlinked;
273 for (rbufp = HEAD_FIFO(full_recv_fifo);
277 # ifdef HAVE_IO_COMPLETION_PORT
278 if (rbufp->dstadr == NULL && rbufp->fd == fd)
283 UNLINK_MID_FIFO(punlinked, full_recv_fifo,
284 rbufp, link, recvbuf_t);
285 INSIST(punlinked == rbufp);
296 * Checks to see if there are buffers to process
298 isc_boolean_t has_full_recv_buffer(void)
300 if (HEAD_FIFO(full_recv_fifo) != NULL)
307 #ifdef NTP_DEBUG_LISTS_H
309 check_gen_fifo_consistency(void *fifo)
316 REQUIRE((NULL == pf->phead && NULL == pf->pptail) ||
317 (NULL != pf->phead && NULL != pf->pptail));
320 for (pthis = pf->phead;
323 if (NULL != pthis->link)
324 pptail = &pthis->link;
326 REQUIRE(NULL == pf->pptail || pptail == pf->pptail);
328 #endif /* NTP_DEBUG_LISTS_H */