1 /* $NetBSD: recvbuff.c,v 1.6 2007/08/18 13:18:23 kardel Exp $ */
8 #include "ntp_machine.h"
10 #include "ntp_syslog.h"
11 #include "ntp_stdlib.h"
20 static u_long
volatile full_recvbufs
; /* number of recvbufs on fulllist */
21 static u_long
volatile free_recvbufs
; /* number of recvbufs on freelist */
22 static u_long
volatile total_recvbufs
; /* total recvbufs currently in use */
23 static u_long
volatile lowater_adds
; /* number of times we have added memory */
24 static u_long
volatile buffer_shortfall
;/* number of missed free receive buffers
25 between replenishments */
27 static ISC_LIST(recvbuf_t
) full_recv_list
; /* Currently used recv buffers */
28 static ISC_LIST(recvbuf_t
) free_recv_list
; /* Currently unused buffers */
30 #if defined(SYS_WINNT)
33 * For Windows we need to set up a lock to manipulate the
34 * recv buffers to prevent corruption. We keep it lock for as
35 * short a time as possible
37 static CRITICAL_SECTION RecvLock
;
38 # define LOCK() EnterCriticalSection(&RecvLock)
39 # define UNLOCK() LeaveCriticalSection(&RecvLock)
58 total_recvbuffs (void)
60 return total_recvbufs
;
64 lowater_additions(void)
70 initialise_buffer(recvbuf_t
*buff
)
72 memset((char *) buff
, 0, sizeof(recvbuf_t
));
75 buff
->wsabuff
.len
= RX_BUFF_SIZE
;
76 buff
->wsabuff
.buf
= (char *) buff
->recv_buffer
;
81 create_buffers(int nbufs
)
83 register recvbuf_t
*bufp
;
86 abuf
= nbufs
+ buffer_shortfall
;
89 bufp
= (recvbuf_t
*) emalloc(abuf
*sizeof(recvbuf_t
));
91 for (i
= 0; i
< abuf
; i
++)
93 memset((char *) bufp
, 0, sizeof(recvbuf_t
));
94 ISC_LIST_APPEND(free_recv_list
, bufp
, link
);
103 init_recvbuff(int nbufs
)
107 * Init buffer free list and stat counters
109 ISC_LIST_INIT(full_recv_list
);
110 ISC_LIST_INIT(free_recv_list
);
111 free_recvbufs
= total_recvbufs
= 0;
112 full_recvbufs
= lowater_adds
= 0;
114 create_buffers(nbufs
);
116 #if defined(SYS_WINNT)
117 InitializeCriticalSection(&RecvLock
);
123 * freerecvbuf - make a single recvbuf available for reuse
126 freerecvbuf(recvbuf_t
*rb
)
129 msyslog(LOG_ERR
, "freerecvbuff received NULL buffer");
136 msyslog(LOG_ERR
, "******** freerecvbuff non-zero usage: %d *******", rb
->used
);
137 ISC_LIST_APPEND(free_recv_list
, rb
, link
);
138 #if defined SYS_WINNT
139 rb
->wsabuff
.len
= RX_BUFF_SIZE
;
140 rb
->wsabuff
.buf
= (char *) rb
->recv_buffer
;
148 add_full_recv_buffer(recvbuf_t
*rb
)
151 msyslog(LOG_ERR
, "add_full_recv_buffer received NULL buffer");
155 ISC_LIST_APPEND(full_recv_list
, rb
, link
);
161 get_free_recv_buffer(void)
163 recvbuf_t
* buffer
= NULL
;
165 buffer
= ISC_LIST_HEAD(free_recv_list
);
168 ISC_LIST_DEQUEUE(free_recv_list
, buffer
, link
);
170 initialise_buffer(buffer
);
181 #ifdef HAVE_IO_COMPLETION_PORT
183 get_free_recv_buffer_alloc(void)
185 recvbuf_t
* buffer
= get_free_recv_buffer();
188 create_buffers(RECV_INC
);
189 buffer
= get_free_recv_buffer();
196 get_full_recv_buffer(void)
201 #ifdef HAVE_SIGNALED_IO
203 * make sure there are free buffers when we
204 * wander off to do lengthy paket processing with
205 * any buffer we grab from the full list.
207 * fixes malloc() interrupted by SIGIO risk
210 rbuf
= ISC_LIST_HEAD(free_recv_list
);
211 if (rbuf
== NULL
|| buffer_shortfall
> 0) {
213 * try to get us some more buffers
215 create_buffers(RECV_INC
);
220 * try to grab a full buffer
222 rbuf
= ISC_LIST_HEAD(full_recv_list
);
225 ISC_LIST_DEQUEUE(full_recv_list
, rbuf
, link
);
231 * Make sure we reset the full count to 0
240 * Checks to see if there are buffers to process
242 isc_boolean_t
has_full_recv_buffer(void)
244 if (ISC_LIST_HEAD(full_recv_list
) != NULL
)