6 #include "ntp_machine.h"
8 #include "ntp_syslog.h"
9 #include "ntp_stdlib.h"
18 static u_long volatile full_recvbufs; /* number of recvbufs on fulllist */
19 static u_long volatile free_recvbufs; /* number of recvbufs on freelist */
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 ISC_LIST(recvbuf_t) full_recv_list; /* Currently used recv buffers */
26 static ISC_LIST(recvbuf_t) free_recv_list; /* Currently unused buffers */
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)
56 total_recvbuffs (void)
58 return total_recvbufs;
62 lowater_additions(void)
68 initialise_buffer(recvbuf_t *buff)
70 memset((char *) buff, 0, sizeof(recvbuf_t));
73 buff->wsabuff.len = RX_BUFF_SIZE;
74 buff->wsabuff.buf = (char *) buff->recv_buffer;
79 create_buffers(int nbufs)
81 register recvbuf_t *bufp;
84 abuf = nbufs + buffer_shortfall;
87 bufp = (recvbuf_t *) emalloc(abuf*sizeof(recvbuf_t));
89 for (i = 0; i < abuf; i++)
91 memset((char *) bufp, 0, sizeof(recvbuf_t));
92 ISC_LIST_APPEND(free_recv_list, bufp, link);
101 init_recvbuff(int nbufs)
105 * Init buffer free list and stat counters
107 ISC_LIST_INIT(full_recv_list);
108 ISC_LIST_INIT(free_recv_list);
109 free_recvbufs = total_recvbufs = 0;
110 full_recvbufs = lowater_adds = 0;
112 create_buffers(nbufs);
114 #if defined(SYS_WINNT)
115 InitializeCriticalSection(&RecvLock);
121 * freerecvbuf - make a single recvbuf available for reuse
124 freerecvbuf(recvbuf_t *rb)
127 msyslog(LOG_ERR, "freerecvbuff received NULL buffer");
134 msyslog(LOG_ERR, "******** freerecvbuff non-zero usage: %d *******", rb->used);
135 ISC_LIST_APPEND(free_recv_list, rb, link);
136 #if defined SYS_WINNT
137 rb->wsabuff.len = RX_BUFF_SIZE;
138 rb->wsabuff.buf = (char *) rb->recv_buffer;
146 add_full_recv_buffer(recvbuf_t *rb)
149 msyslog(LOG_ERR, "add_full_recv_buffer received NULL buffer");
153 ISC_LIST_APPEND(full_recv_list, rb, link);
159 get_free_recv_buffer(void)
161 recvbuf_t * buffer = NULL;
163 buffer = ISC_LIST_HEAD(free_recv_list);
166 ISC_LIST_DEQUEUE(free_recv_list, buffer, link);
168 initialise_buffer(buffer);
179 #ifdef HAVE_IO_COMPLETION_PORT
181 get_free_recv_buffer_alloc(void)
183 recvbuf_t * buffer = get_free_recv_buffer();
186 create_buffers(RECV_INC);
187 buffer = get_free_recv_buffer();
194 get_full_recv_buffer(void)
199 #ifdef HAVE_SIGNALED_IO
201 * make sure there are free buffers when we
202 * wander off to do lengthy paket processing with
203 * any buffer we grab from the full list.
205 * fixes malloc() interrupted by SIGIO risk
208 rbuf = ISC_LIST_HEAD(free_recv_list);
209 if (rbuf == NULL || buffer_shortfall > 0) {
211 * try to get us some more buffers
213 create_buffers(RECV_INC);
218 * try to grab a full buffer
220 rbuf = ISC_LIST_HEAD(full_recv_list);
223 ISC_LIST_DEQUEUE(full_recv_list, rbuf, link);
229 * Make sure we reset the full count to 0
238 * Checks to see if there are buffers to process
240 isc_boolean_t has_full_recv_buffer(void)
242 if (ISC_LIST_HEAD(full_recv_list) != NULL)