From: Dave Hart Date: Thu, 16 Jul 2009 16:23:37 +0000 (+0000) Subject: [Bug 1246] use a common template for singly-linked lists, convert most X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=84be70eb49048e07c244255385505d424fd4276f;p=thirdparty%2Fntp.git [Bug 1246] use a common template for singly-linked lists, convert most doubly-linked lists to singly-linked. bk: 4a5f5409mcVB8S7OBSMxwMH2aza67w --- diff --git a/ChangeLog b/ChangeLog index 4d07fe48f5..28b9024c77 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,5 @@ +* [Bug 1246] use a common template for singly-linked lists, convert most + doubly-linked lists to singly-linked. (4.2.5p185) 2009/07/01 Released by Harlan Stenn * Documentation updates from Dave Mills. * [Bug 1234] convert NMEA driver to use common PPSAPI code. diff --git a/include/ntp.h b/include/ntp.h index 120a3e01df..562c48d9e2 100644 --- a/include/ntp.h +++ b/include/ntp.h @@ -15,7 +15,6 @@ #include #include -#include /* * Calendar arithmetic - contributed by G. Healton @@ -175,28 +174,28 @@ typedef char s_char; * numbers of each of the interfaces we are using. */ struct interface { - SOCKET fd; /* socket this is opened on */ - SOCKET bfd; /* socket for receiving broadcasts */ - sockaddr_u sin; /* interface address */ - sockaddr_u bcast; /* broadcast address */ - sockaddr_u mask; /* interface mask */ - char name[32]; /* name of interface */ - u_short family; /* Address family */ - u_short phase; /* phase in update cycle */ - int flags; /* interface flags */ - int last_ttl; /* last TTL specified */ - u_int32 addr_refid; /* IPv4 addr or IPv6 hash */ - int num_mcast; /* No. of IP addresses in multicast socket */ - u_long starttime; /* current_time as of creation of interface structure */ - volatile long received; /* number of incoming packets */ - long sent; /* number of outgoing packets */ - long notsent; /* number of send failures */ - u_int scopeid; /* Scope used for Multicasting */ - u_int ifnum; /* sequential interface instance count */ - isc_boolean_t ignore_packets; /* listen-read-drop this? */ - ISC_LIST(struct peer) peers; /* list of peers for the interface */ - u_int peercnt; /* peers referencing this interface */ - ISC_LINK(struct interface) link;/* interface list */ + struct interface *link; /* interface list link */ + SOCKET fd; /* socket this is opened on */ + SOCKET bfd; /* socket for receiving broadcasts */ + sockaddr_u sin; /* interface address */ + sockaddr_u bcast; /* broadcast address */ + sockaddr_u mask; /* interface mask */ + char name[32]; /* name of interface */ + u_short family; /* Address family */ + u_short phase; /* phase in update cycle */ + int flags; /* interface flags */ + int last_ttl; /* last TTL specified */ + u_int32 addr_refid; /* IPv4 addr or IPv6 hash */ + int num_mcast; /* No. of IP addresses in multicast socket */ + u_long starttime; /* current_time as of creation of interface structure */ + volatile long received; /* number of incoming packets */ + long sent; /* number of outgoing packets */ + long notsent; /* number of send failures */ + u_int scopeid; /* Scope used for Multicasting */ + u_int ifnum; /* sequential interface instance count */ + isc_boolean_t ignore_packets; /* listen-read-drop this? */ + struct peer *peers; /* list of peers for the interface */ + u_int peercnt; /* peers referencing this interface */ }; /* @@ -246,11 +245,11 @@ struct interface { * spec. */ struct peer { - struct peer *next; /* pointer to next association */ + struct peer *next; /* link pointer in peer hash */ struct peer *ass_next; /* link pointer in associd hash */ + struct peer *ilink; /* list of peers for interface */ sockaddr_u srcadr; /* address of remote host */ struct interface *dstadr; /* local address (interface) */ - ISC_LINK(struct peer) ilink; /* peers using this interface */ associd_t associd; /* association ID */ u_char version; /* version number */ u_char hmode; /* local association mode */ diff --git a/include/ntp_io.h b/include/ntp_io.h index 297adae29b..33a2e00c92 100644 --- a/include/ntp_io.h +++ b/include/ntp_io.h @@ -1,5 +1,5 @@ -#if !defined _NTP_IO_H -#define _NTP_IO_H +#ifndef NTP_IO_H +#define NTP_IO_H /* * POSIX says use to get O_* symbols and * SEEK_SET symbol form . @@ -60,9 +60,7 @@ isc_boolean_t get_broadcastclient_flag(void); /* Get the status of client broadcast */ extern void add_specific_interface (const char *); -extern void init_specific_interface (void); extern void add_limit_address (const isc_netaddr_t *); -extern void init_limit_address (void); isc_boolean_t is_ip_address(const char *, isc_netaddr_t *); -#endif +#endif /* NTP_IO_H */ diff --git a/include/ntp_lists.h b/include/ntp_lists.h new file mode 100644 index 0000000000..2bac38a52c --- /dev/null +++ b/include/ntp_lists.h @@ -0,0 +1,104 @@ +/* + * ntp_lists.h - singly-linked lists common code + * + * These macros implement a simple singly-linked list template. Both + * the listhead and per-entry next fields are declared as pointers to + * the list entry struct type. Initialization to NULL is typically + * implicit (for globals and statics) or handled by zeroing of the + * containing structure. + * + * The name of the next link field is passed as an argument to allow + * membership in several lists at once using multiple next link fields. + * + * When possible, placing the link field first in the entry structure + * allows slightly smaller code to be generated on some platforms. + * + * LINK_SLIST(listhead, pentry, nextlink) + * add entry at head + * + * LINK_TAIL_SLIST(listhead, pentry, nextlink, entrytype) + * add entry at tail + * + * UNLINK_HEAD_SLIST(punlinked, listhead, nextlink) + * unlink first entry and point punlinked to it, or set punlinked + * to NULL if the list is empty. + * + * UNLINK_SLIST(punlinked, listhead, ptounlink, nextlink, entrytype) + * unlink entry pointed to by ptounlink. punlinked is set to NULL + * if the entry is not found on the list, otherwise it is set to + * ptounlink. + * + * UNLINK_EXPR_SLIST(punlinked, listhead, expr, nextlink, entrytype) + * unlink entry where expression expr is nonzero. expr can refer + * to the entry being tested using UNLINK_EXPR_SLIST_CURRENT(). + * See the implementation of UNLINK_SLIST() below for an example. + * punlinked is pointed to the removed entry or NULL if none + * satisfy expr. + */ +#ifndef NTP_LISTS_H +#define NTP_LISTS_H + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + + +#define LINK_SLIST(listhead, pentry, nextlink) \ +do { \ + (pentry)->nextlink = (listhead); \ + (listhead) = (pentry); \ +} while (0) + +#define LINK_TAIL_SLIST(listhead, pentry, nextlink, entrytype) \ +do { \ + entrytype **pptail; \ + \ + pptail = &(listhead); \ + while (*pptail != NULL) \ + pptail = &((*pptail)->nextlink); \ + \ + (pentry)->nextlink = NULL; \ + *pptail = (pentry); \ +} while (0) + +#define UNLINK_HEAD_SLIST(punlinked, listhead, nextlink) \ +do { \ + (punlinked) = (listhead); \ + if (NULL != (punlinked)) { \ + (listhead) = (punlinked)->nextlink; \ + (punlinked)->nextlink = NULL; \ + } \ +} while (0) + +#define UNLINK_EXPR_SLIST(punlinked, listhead, expr, nextlink, \ + entrytype) \ +do { \ + entrytype **ppentry; \ + \ + ppentry = &(listhead); \ + \ + while (!(expr)) \ + if ((*ppentry)->nextlink != NULL) \ + ppentry = &((*ppentry)->nextlink); \ + else { \ + ppentry = NULL; \ + break; \ + } \ + \ + if (ppentry != NULL) { \ + (punlinked) = *ppentry; \ + *ppentry = (punlinked)->nextlink; \ + (punlinked)->nextlink = NULL; \ + } else \ + (punlinked) = NULL; \ +} while (0) +#define UNLINK_EXPR_SLIST_CURRENT() (*ppentry) + +#define UNLINK_SLIST(punlinked, listhead, ptounlink, nextlink, \ + entrytype) \ + UNLINK_EXPR_SLIST(punlinked, listhead, (ptounlink) == \ + UNLINK_EXPR_SLIST_CURRENT(), nextlink, entrytype) + +#endif /* NTP_LISTS_H */ diff --git a/include/recvbuff.h b/include/recvbuff.h index 32ff76a5e1..1fdc54a4d7 100644 --- a/include/recvbuff.h +++ b/include/recvbuff.h @@ -1,5 +1,5 @@ -#if !defined __recvbuff_h -#define __recvbuff_h +#ifndef RECVBUFF_H +#define RECVBUFF_H #ifdef HAVE_CONFIG_H # include @@ -7,8 +7,8 @@ #include "ntp.h" #include "ntp_fp.h" +#include "ntp_lists.h" -#include #include /* @@ -51,7 +51,7 @@ extern HANDLE get_recv_buff_event (void); typedef struct recvbuf recvbuf_t; struct recvbuf { - ISC_LINK(recvbuf_t) link; + ISC_LINK(recvbuf_t) link; /* next in list */ union { sockaddr_u X_recv_srcadr; caddr_t X_recv_srcclock; @@ -117,5 +117,4 @@ extern struct recvbuf *get_full_recv_buffer (void); */ extern isc_boolean_t has_full_recv_buffer (void); -#endif /* defined __recvbuff_h */ - +#endif /* RECVBUFF_H */ diff --git a/libntp/recvbuff.c b/libntp/recvbuff.c index a105007dfb..9a7d6caf43 100644 --- a/libntp/recvbuff.c +++ b/libntp/recvbuff.c @@ -9,10 +9,10 @@ #include "ntp_syslog.h" #include "ntp_stdlib.h" #include "ntp_io.h" +#include "ntp_lists.h" #include "recvbuff.h" #include "iosignal.h" -#include #ifdef DEBUG @@ -30,7 +30,7 @@ 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 ISC_LIST(recvbuf_t) free_recv_list; /* Currently unused buffers */ +static recvbuf_t * free_recv_list; /* Currently unused buffers */ #if defined(SYS_WINNT) @@ -100,7 +100,7 @@ create_buffers(int nbufs) bufp = emalloc(sizeof(*bufp)); #endif memset(bufp, 0, sizeof(*bufp)); - ISC_LIST_APPEND(free_recv_list, bufp, link); + LINK_SLIST(free_recv_list, bufp, link.next); bufp++; free_recvbufs++; total_recvbufs++; @@ -116,7 +116,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; @@ -136,23 +135,18 @@ init_recvbuff(int nbufs) static void uninit_recvbuff(void) { - recvbuf_t * rb; + recvbuf_t *rbunlinked; - for (rb = ISC_LIST_HEAD(full_recv_list); - rb != NULL; - rb = ISC_LIST_HEAD(full_recv_list)) { - - ISC_LIST_DEQUEUE(full_recv_list, rb, link); - free(rb); + while ((rbunlinked = ISC_LIST_HEAD(full_recv_list)) != NULL) { + ISC_LIST_DEQUEUE_TYPE(full_recv_list, rbunlinked, link, recvbuf_t); + free(rbunlinked); } - for (rb = ISC_LIST_HEAD(free_recv_list); - rb != NULL; - rb = ISC_LIST_HEAD(free_recv_list)) { - - ISC_LIST_DEQUEUE(free_recv_list, rb, link); - free(rb); - } + do { + UNLINK_HEAD_SLIST(rbunlinked, free_recv_list, link.next); + if (rbunlinked != NULL) + free(rbunlinked); + } while (rbunlinked != NULL); } #endif /* DEBUG */ @@ -172,7 +166,7 @@ freerecvbuf(recvbuf_t *rb) (rb->used)--; if (rb->used != 0) msyslog(LOG_ERR, "******** freerecvbuff non-zero usage: %d *******", rb->used); - ISC_LIST_APPEND(free_recv_list, rb, link); + LINK_SLIST(free_recv_list, rb, link.next); free_recvbufs++; UNLOCK(); } @@ -186,6 +180,7 @@ add_full_recv_buffer(recvbuf_t *rb) return; } LOCK(); + ISC_LINK_INIT(rb, link); ISC_LIST_APPEND(full_recv_list, rb, link); full_recvbufs++; UNLOCK(); @@ -194,20 +189,16 @@ add_full_recv_buffer(recvbuf_t *rb) 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.next); + if (buffer != NULL) { free_recvbufs--; initialise_buffer(buffer); (buffer->used)++; - } - else - { + } else buffer_shortfall++; - } UNLOCK(); return (buffer); } @@ -216,13 +207,14 @@ get_free_recv_buffer(void) 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(NULL != buffer); + NTP_ENSURE(buffer != NULL); return (buffer); } #endif @@ -236,14 +228,13 @@ get_full_recv_buffer(void) #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 */ @@ -255,18 +246,14 @@ get_full_recv_buffer(void) * try to grab a full buffer */ rbuf = ISC_LIST_HEAD(full_recv_list); - if (rbuf != NULL) - { - ISC_LIST_DEQUEUE(full_recv_list, rbuf, link); + if (rbuf != NULL) { + ISC_LIST_DEQUEUE_TYPE(full_recv_list, rbuf, link, recvbuf_t); --full_recvbufs; - } - else - { + } else /* * Make sure we reset the full count to 0 */ full_recvbufs = 0; - } UNLOCK(); return (rbuf); } diff --git a/ntpd/ntp_io.c b/ntpd/ntp_io.c index 19b8cfb072..6cc0194cf5 100644 --- a/ntpd/ntp_io.c +++ b/ntpd/ntp_io.c @@ -26,6 +26,7 @@ #include "ntpd.h" #include "ntp_io.h" #include "iosignal.h" +#include "ntp_lists.h" #include "ntp_refclock.h" #include "ntp_stdlib.h" #include "ntp_request.h" @@ -36,7 +37,6 @@ /* Don't include ISC's version of IPv6 variables and structures */ #define ISC_IPV6_H 1 #include -#include #include #include #include @@ -83,21 +83,21 @@ int interface_optioncount = 0; */ typedef struct specific_interface specific_interface_t; struct specific_interface { + specific_interface_t *link; const char *name; - ISC_LINK(specific_interface_t) link; }; -ISC_LIST(specific_interface_t) specific_interface_list; +specific_interface_t *specific_interface_list; /* * limit addresses to use */ typedef struct limit_address limit_address_t; struct limit_address { + limit_address_t *link; const isc_netaddr_t *addr; - ISC_LINK(limit_address_t) link; }; -ISC_LIST(limit_address_t) limit_address_list; +limit_address_t *limit_address_list; #if defined(SO_TIMESTAMP) && defined(SCM_TIMESTAMP) @@ -225,11 +225,13 @@ typedef struct vsock vsock_t; enum desc_type { FD_TYPE_SOCKET, FD_TYPE_FILE }; struct vsock { - SOCKET fd; - enum desc_type type; - ISC_LINK(vsock_t) link; + vsock_t * link; + SOCKET fd; + enum desc_type type; }; +vsock_t *fd_list; + #if !defined(HAVE_IO_COMPLETION_PORT) && defined(HAS_ROUTING_SOCKET) /* * async notification processing (e. g. routing sockets) @@ -239,13 +241,13 @@ struct vsock { * like e. g. routing sockets */ struct asyncio_reader { + struct asyncio_reader *link; /* the list this is being kept in */ SOCKET fd; /* fd to be read */ void *data; /* possibly local data */ void (*receiver)(struct asyncio_reader *); /* input handler */ - ISC_LINK(struct asyncio_reader) link; /* the list this is being kept in */ }; -ISC_LIST(struct asyncio_reader) asyncio_reader_list; +struct asyncio_reader *asyncio_reader_list; static void delete_asyncio_reader (struct asyncio_reader *); static struct asyncio_reader *new_asyncio_reader (void); @@ -263,19 +265,17 @@ static void set_reuseaddr (int); static isc_boolean_t socket_broadcast_enable (struct interface *, SOCKET, sockaddr_u *); static isc_boolean_t socket_broadcast_disable (struct interface *, sockaddr_u *); -ISC_LIST(vsock_t) fd_list; - typedef struct remaddr remaddr_t; struct remaddr { + remaddr_t * link; sockaddr_u addr; struct interface * interface; - ISC_LINK(remaddr_t) link; }; -ISC_LIST(remaddr_t) remoteaddr_list; +remaddr_t * remoteaddr_list; -ISC_LIST(struct interface) inter_list; +struct interface * inter_list; static struct interface *wildipv4 = NULL; static struct interface *wildipv6 = NULL; @@ -542,16 +542,6 @@ init_io(void) (void) set_signal(); #endif - ISC_LIST_INIT(fd_list); - -#if !defined(HAVE_IO_COMPLETION_PORT) && defined(HAS_ROUTING_SOCKET) - ISC_LIST_INIT(asyncio_reader_list); -#endif - - ISC_LIST_INIT(remoteaddr_list); - - ISC_LIST_INIT(inter_list); - /* * Create the sockets */ @@ -658,7 +648,6 @@ new_asyncio_reader(void) reader = emalloc(sizeof(*reader)); memset(reader, 0, sizeof(*reader)); - ISC_LINK_INIT(reader, link); reader->fd = INVALID_SOCKET; return reader; } @@ -682,7 +671,7 @@ add_asyncio_reader( struct asyncio_reader * reader, enum desc_type type) { - ISC_LIST_APPEND(asyncio_reader_list, reader, link); + LINK_SLIST(asyncio_reader_list, reader, link); add_fd_to_list(reader->fd, type); } @@ -694,8 +683,10 @@ remove_asyncio_reader( struct asyncio_reader *reader ) { - ISC_LIST_UNLINK_TYPE(asyncio_reader_list, reader, link, - struct asyncio_reader); + struct asyncio_reader *unlinked; + + UNLINK_SLIST(unlinked, asyncio_reader_list, reader, link, + struct asyncio_reader); if (reader->fd != INVALID_SOCKET) close_and_delete_fd_from_list(reader->fd); @@ -772,19 +763,12 @@ add_specific_interface( free(naddr); siface = emalloc(sizeof(*siface)); siface->name = if_name; - ISC_LINK_INIT(siface, link); - ISC_LIST_APPEND(specific_interface_list, siface, link); + LINK_TAIL_SLIST(specific_interface_list, siface, link, + specific_interface_t); } interface_optioncount++; } -void -init_specific_interface(void) -{ - ISC_LIST_INIT(specific_interface_list); - init_limit_address(); -} - /* * Limit address code */ @@ -797,13 +781,8 @@ add_limit_address( iaddr = emalloc(sizeof(*iaddr)); iaddr->addr = addr; - ISC_LIST_APPEND(limit_address_list, iaddr, link); -} - -void -init_limit_address(void) -{ - ISC_LIST_INIT(limit_address_list); + LINK_TAIL_SLIST(limit_address_list, iaddr, link, + limit_address_t); } /* @@ -816,16 +795,13 @@ interface_enumerate( ) { interface_info_t ifi; - struct interface *interf; ifi.action = IFS_EXISTS; - for (interf = ISC_LIST_HEAD(inter_list); - interf != NULL; - interf = ISC_LIST_NEXT(interf, link)) { - ifi.interface = interf; + for (ifi.interface = inter_list; + ifi.interface != NULL; + ifi.interface = ifi.interface->link) (*receiver)(data, &ifi); - } } /* @@ -837,8 +813,6 @@ init_interface( ) { memset(iface, 0, sizeof(*iface)); - ISC_LINK_INIT(iface, link); - ISC_LIST_INIT(iface->peers); iface->fd = INVALID_SOCKET; iface->bfd = INVALID_SOCKET; iface->phase = sys_interphase; @@ -893,32 +867,12 @@ add_interface( struct interface *interface ) { -#ifdef DEBUG - static struct interface *listhead = NULL; - - /* - * For ntpd, the first few interfaces (wildcard, localhost) - * will never be removed. This means inter_list.head is - * unchanging once initialized. Take advantage of that to - * watch for changes and catch corruption earlier. This - * helped track down corruption caused by using FD_SET with - * a descriptor numerically larger than FD_SETSIZE. - */ - if (NULL == listhead) - listhead = inter_list.head; - - if (listhead != inter_list.head) { - msyslog(LOG_ERR, "add_interface inter_list.head corrupted: was %p now %p", - listhead, inter_list.head); - exit(1); - } -#endif /* * Calculate the address hash */ interface->addr_refid = addr2refid(&interface->sin); - - ISC_LIST_APPEND(inter_list, interface, link); + + LINK_SLIST(inter_list, interface, link); ninterfaces++; } @@ -932,10 +886,11 @@ remove_interface( struct interface *iface ) { + struct interface *unlinked; sockaddr_u resmask; - ISC_LIST_UNLINK_TYPE(inter_list, iface, link, - struct interface); + UNLINK_SLIST(unlinked, inter_list, iface, link, struct + interface); delete_interface_from_list(iface); @@ -1104,9 +1059,9 @@ address_okay( * Check if the IP address matches one given to -I, which limits * interfaces/addresses to be used to only those listed with -I. */ - for (laddr = ISC_LIST_HEAD(limit_address_list); - NULL != laddr; - laddr = ISC_LIST_NEXT(laddr, link)) + for (laddr = limit_address_list; + laddr != NULL; + laddr = laddr->link) if (isc_netaddr_equal(&isc_if->address, laddr->addr)) { DPRINTF(4, ("address_okay: specific interface address matched - OK\n")); return (ISC_TRUE); @@ -1114,9 +1069,9 @@ address_okay( /* * Check if the interface name was specified with an -I option. */ - for (iface = ISC_LIST_HEAD(specific_interface_list); + for (iface = specific_interface_list; NULL != iface; - iface = ISC_LIST_NEXT(iface, link)) + iface = iface->link) if (!strcasecmp(isc_if->name, iface->name)) { DPRINTF(4, ("address_okay: specific interface name matched - OK\n")); return (ISC_TRUE); @@ -1350,7 +1305,6 @@ update_interfaces( struct interface interface; struct interface * iface; struct interface * next; - struct peer * peer; DPRINTF(3, ("update_interfaces(%d)\n", port)); @@ -1542,10 +1496,10 @@ update_interfaces( * phase 2 - delete gone interfaces - reassigning peers to * other interfaces */ - iface = ISC_LIST_HEAD(inter_list); + iface = inter_list; while (iface != NULL) { - next = ISC_LIST_NEXT(iface, link); + next = iface->link; if (!(iface->flags & (INT_WILDCARD | INT_MCASTIF))) { /* @@ -1570,10 +1524,8 @@ update_interfaces( * disconnect peers from deleted * interface */ - for (peer = ISC_LIST_HEAD(iface->peers); - peer != NULL; - peer = ISC_LIST_HEAD(iface->peers)) - set_peerdstadr(peer, NULL); + while (iface->peers != NULL) + set_peerdstadr(iface->peers, NULL); /* * update globals in case we lose @@ -1753,9 +1705,9 @@ set_reuseaddr( #ifndef SO_EXCLUSIVEADDRUSE - for (interf = ISC_LIST_HEAD(inter_list); + for (interf = inter_list; interf != NULL; - interf = ISC_LIST_NEXT(interf, link)) { + interf = interf->link) { if (interf->flags & INT_WILDCARD) continue; @@ -2158,9 +2110,9 @@ io_setbclient(void) nif = 0; set_reuseaddr(1); - for (interf = ISC_LIST_HEAD(inter_list); + for (interf = inter_list; interf != NULL; - interf = ISC_LIST_NEXT(interf, link)) { + interf = interf->link) { if (interf->flags & (INT_WILDCARD | INT_LOOPBACK)) continue; @@ -2235,9 +2187,9 @@ io_unsetbclient(void) { struct interface *interf; - for (interf = ISC_LIST_HEAD(inter_list); + for (interf = inter_list; NULL != interf; - interf = ISC_LIST_NEXT(interf, link)) + interf = interf->link) { if (interf->flags & INT_WILDCARD) continue; @@ -3163,9 +3115,9 @@ input_handler( /* * Loop through the interfaces looking for data to read. */ - for (interface = ISC_LIST_TAIL(inter_list); + for (interface = inter_list; interface != NULL; - interface = ISC_LIST_PREV(interface, link)) { + interface = interface->link) { for (doing = 0; (doing < 2); doing++) { if (!doing) @@ -3192,17 +3144,14 @@ input_handler( /* * scan list of asyncio readers - currently only used for routing sockets */ - asyncio_reader = ISC_LIST_TAIL(asyncio_reader_list); + asyncio_reader = asyncio_reader_list; while (asyncio_reader != NULL) { - struct asyncio_reader *next; - - next = ISC_LIST_PREV(asyncio_reader, link); if (FD_ISSET(asyncio_reader->fd, &fds)) { ++select_count; - asyncio_reader->receiver(asyncio_reader); + (asyncio_reader->receiver)(asyncio_reader); } - asyncio_reader = next; + asyncio_reader = asyncio_reader->link; } #endif /* HAS_ROUTING_SOCKET */ @@ -3421,9 +3370,9 @@ findlocalcastinterface( || IN6_IS_ADDR_MC_SITELOCAL(PSOCK_ADDR6(addr))); #endif - for (iface = ISC_LIST_HEAD(inter_list); + for (iface = inter_list; iface != NULL; - iface = ISC_LIST_NEXT(iface, link)) + iface = iface->link) { /* use only allowed addresses */ if (iface->ignore_packets) @@ -3492,9 +3441,9 @@ findbcastinter( * plan B - try to find something reasonable in our lists in * case kernel lookup doesn't help */ - for (iface = ISC_LIST_HEAD(inter_list); + for (iface = inter_list; iface != NULL; - iface = ISC_LIST_NEXT(iface, link)) + iface = iface->link) { if (iface->flags & INT_WILDCARD) continue; @@ -3677,25 +3626,17 @@ io_closeclock( void kill_asyncio(int startfd) { - vsock_t *lsock; - vsock_t *next; - BLOCKIO(); - lsock = ISC_LIST_HEAD(fd_list); - while (lsock != NULL) { - /* - * careful here - list is being dismantled while - * we scan it - setting next here insures that - * we are able to correctly scan the list - */ - next = ISC_LIST_NEXT(lsock, link); - /* - * will remove socket from list - */ - close_and_delete_fd_from_list(lsock->fd); - lsock = next; - } + /* + * In the child process we do not maintain activefds and + * maxactivefd. Zeroing maxactivefd disables code which + * maintains it in close_and_delete_fd_from_list(). + */ + maxactivefd = 0; + + while (fd_list != NULL) + close_and_delete_fd_from_list(fd_list->fd); UNBLOCKIO(); } @@ -3714,7 +3655,7 @@ add_fd_to_list( lsock->fd = fd; lsock->type = type; - ISC_LIST_APPEND(fd_list, lsock, link); + LINK_SLIST(fd_list, lsock, link); /* * I/O Completion Ports don't care about the select and FD_SET */ @@ -3739,55 +3680,49 @@ close_and_delete_fd_from_list( SOCKET fd ) { - vsock_t *next; - vsock_t *lsock = ISC_LIST_HEAD(fd_list); - - while(lsock != NULL) { - next = ISC_LIST_NEXT(lsock, link); - if(lsock->fd == fd) { - ISC_LIST_DEQUEUE_TYPE(fd_list, lsock, link, - vsock_t); - - switch (lsock->type) { - case FD_TYPE_SOCKET: - closesocket(lsock->fd); - break; + vsock_t *lsock; - case FD_TYPE_FILE: - close(lsock->fd); - break; + UNLINK_EXPR_SLIST(lsock, fd_list, fd == + UNLINK_EXPR_SLIST_CURRENT()->fd, link, vsock_t); - default: - msyslog(LOG_ERR, - "internal error - illegal descriptor type %d - EXITING", - (int)lsock->type); - exit(1); - } + if (lsock != NULL) { + switch (lsock->type) { + case FD_TYPE_SOCKET: + closesocket(lsock->fd); + break; - free(lsock); - /* - * I/O Completion Ports don't care about select and fd_set - */ -#ifndef HAVE_IO_COMPLETION_PORT - /* - * remove from activefds - */ - FD_CLR(fd, &activefds); - - if (fd == maxactivefd && maxactivefd) { - int i; - NTP_INSIST(maxactivefd - 1 < FD_SETSIZE); - for (i = maxactivefd - 1; i >= 0; i--) - if (FD_ISSET(i, &activefds)) { - maxactivefd = i; - break; - } - NTP_INSIST(fd != maxactivefd); - } -#endif + case FD_TYPE_FILE: + close(lsock->fd); break; + + default: + msyslog(LOG_ERR, + "internal error - illegal descriptor type %d - EXITING", + (int)lsock->type); + exit(1); + } + + free(lsock); + /* + * I/O Completion Ports don't care about select and fd_set + */ +#ifndef HAVE_IO_COMPLETION_PORT + /* + * remove from activefds + */ + FD_CLR(fd, &activefds); + + if (fd == maxactivefd && maxactivefd) { + int i; + NTP_INSIST(maxactivefd - 1 < FD_SETSIZE); + for (i = maxactivefd - 1; i >= 0; i--) + if (FD_ISSET(i, &activefds)) { + maxactivefd = i; + break; + } + NTP_INSIST(fd != maxactivefd); } - lsock = next; +#endif } } @@ -3807,7 +3742,7 @@ add_addr_to_list( memcpy(&laddr->addr, addr, sizeof(laddr->addr)); laddr->interface = interface; - ISC_LIST_APPEND(remoteaddr_list, laddr, link); + LINK_SLIST(remoteaddr_list, laddr, link); DPRINTF(4, ("Added addr %s to list of addresses\n", stoa(addr))); @@ -3824,19 +3759,16 @@ delete_addr_from_list( sockaddr_u *addr ) { - remaddr_t *entry; + remaddr_t *unlinked; - for (entry = ISC_LIST_HEAD(remoteaddr_list); - entry != NULL; - entry = ISC_LIST_NEXT(entry, link)) - if (SOCK_EQ(&entry->addr, addr)) { - ISC_LIST_DEQUEUE_TYPE(remoteaddr_list, entry, - link, remaddr_t); - DPRINTF(4, ("Deleted addr %s from list of addresses\n", - stoa(addr))); - free(entry); - break; - } + UNLINK_EXPR_SLIST(unlinked, remoteaddr_list, SOCK_EQ(addr, + &(UNLINK_EXPR_SLIST_CURRENT()->addr)), link, remaddr_t); + + if (unlinked != NULL) { + DPRINTF(4, ("Deleted addr %s from list of addresses\n", + stoa(addr))); + free(unlinked); + } } @@ -3845,22 +3777,15 @@ delete_interface_from_list( struct interface *iface ) { - remaddr_t *next; - remaddr_t *entry; - - entry = ISC_LIST_HEAD(remoteaddr_list); - - while (entry != NULL) { - next = ISC_LIST_NEXT(entry, link); - if (entry->interface == iface) { - ISC_LIST_DEQUEUE_TYPE(remoteaddr_list, entry, - link, remaddr_t); - DPRINTF(4, ("Deleted addr %s for interface #%d %s from list of addresses\n", - stoa(&entry->addr), iface->ifnum, - iface->name)); - free(entry); - } - entry = next; + remaddr_t *unlinked; + + UNLINK_EXPR_SLIST(unlinked, remoteaddr_list, iface == + UNLINK_EXPR_SLIST_CURRENT()->interface, link, remaddr_t); + + if (unlinked != NULL) { + DPRINTF(4, ("Deleted addr %s for interface #%d %s from list of addresses\n", + stoa(&unlinked->addr), iface->ifnum, iface->name)); + free(unlinked); } } @@ -3875,10 +3800,10 @@ find_addr_in_list( DPRINTF(4, ("Searching for addr %s in list of addresses - ", stoa(addr))); - for (entry = ISC_LIST_HEAD(remoteaddr_list); + for (entry = remoteaddr_list; entry != NULL; - entry = ISC_LIST_NEXT(entry, link)) - if(SOCK_EQ(&entry->addr, addr)) { + entry = entry->link) + if (SOCK_EQ(&entry->addr, addr)) { DPRINTF(4, ("FOUND\n")); return entry->interface; } @@ -3962,9 +3887,9 @@ find_samenet_addr_in_list( DPRINTF(4, ("Searching for addr with same subnet as %s in list of addresses - ", stoa(addr))); - for (entry = ISC_LIST_HEAD(remoteaddr_list); + for (entry = remoteaddr_list; entry != NULL; - entry = ISC_LIST_NEXT(entry, link)) + entry = entry->link) if (same_network(&entry->addr, &entry->interface->mask, addr)) { @@ -3991,9 +3916,9 @@ find_flagged_addr_in_list( DPRINTF(4, ("Finding addr %s with flags %d in list: ", stoa(addr), flags)); - for (entry = ISC_LIST_HEAD(remoteaddr_list); + for (entry = remoteaddr_list; entry != NULL; - entry = ISC_LIST_NEXT(entry, link)) + entry = entry->link) if (SOCK_EQ(&entry->addr, addr) && (entry->interface->flags & flags) == flags) { diff --git a/ntpd/ntp_peer.c b/ntpd/ntp_peer.c index 8268f33030..91273aa86c 100644 --- a/ntpd/ntp_peer.c +++ b/ntpd/ntp_peer.c @@ -9,6 +9,7 @@ #include #include "ntpd.h" +#include "ntp_lists.h" #include "ntp_stdlib.h" #include "ntp_control.h" #include @@ -67,8 +68,8 @@ int AM[AM_MODES][AM_MODES] = { /* * These routines manage the allocation of memory to peer structures - * and the maintenance of the peer hash table. The two main entry - * points are findpeer(), which looks for matching peer sturctures in + * and the maintenance of the peer hash table. The three main entry + * points are findpeer(), which looks for matching peer structures in * the peer list, newpeer(), which allocates a new peer structure and * adds it to the list, and unpeer(), which demobilizes the association * and deallocates the structure. @@ -125,14 +126,12 @@ init_peer(void) register int i; /* - * Clear hash table and counters. + * Clear hash tables and counters. */ - for (i = 0; i < NTP_HASH_SIZE; i++) { - peer_hash[i] = 0; - peer_hash_count[i] = 0; - assoc_hash[i] = 0; - assoc_hash_count[i] = 0; - } + memset(peer_hash, 0, sizeof(peer_hash)); + memset(peer_hash_count, 0, sizeof(peer_hash_count)); + memset(assoc_hash, 0, sizeof(assoc_hash)); + memset(assoc_hash_count, 0, sizeof(assoc_hash_count)); /* * Clear stat counters @@ -143,11 +142,9 @@ init_peer(void) /* * Initialize peer memory. */ - peer_free = 0; - for (i = 0; i < INIT_PEER_ALLOC; i++) { - init_peer_alloc[i].next = peer_free; - peer_free = &init_peer_alloc[i]; - } + peer_free = NULL; + for (i = 0; i < INIT_PEER_ALLOC; i++) + LINK_SLIST(peer_free, &init_peer_alloc[i], next); total_peer_structs = INIT_PEER_ALLOC; peer_free_count = INIT_PEER_ALLOC; @@ -170,8 +167,7 @@ getmorepeermem(void) peer = (struct peer *)emalloc(INC_PEER_ALLOC * sizeof(struct peer)); for (i = 0; i < INC_PEER_ALLOC; i++) { - peer->next = peer_free; - peer_free = peer; + LINK_SLIST(peer_free, peer, next); peer++; } @@ -397,6 +393,7 @@ unpeer( struct peer *peer_to_remove ) { + register struct peer *unlinked; int hash; char tbuf[80]; @@ -418,23 +415,14 @@ unpeer( refclock_unpeer(peer_to_remove); #endif peer_to_remove->action = 0; /* disable timeout actions */ - if (peer_hash[hash] == peer_to_remove) { - peer_hash[hash] = peer_to_remove->next; - } else { - register struct peer *peer; - - peer = peer_hash[hash]; - while (peer != 0 && peer->next != peer_to_remove) - peer = peer->next; - - if (peer == 0) { - peer_hash_count[hash]++; - msyslog(LOG_ERR, - "peer struct for %s not in table!", - stoa(&peer->srcadr)); - } else { - peer->next = peer_to_remove->next; - } + + UNLINK_SLIST(unlinked, peer_hash[hash], peer_to_remove, next, + struct peer); + + if (NULL == unlinked) { + peer_hash_count[hash]++; + msyslog(LOG_ERR, "peer struct for %s not in table!", + stoa(&peer_to_remove->srcadr)); } /* @@ -442,26 +430,18 @@ unpeer( */ hash = peer_to_remove->associd & NTP_HASH_MASK; assoc_hash_count[hash]--; - if (assoc_hash[hash] == peer_to_remove) { - assoc_hash[hash] = peer_to_remove->ass_next; - } else { - register struct peer *peer; - - peer = assoc_hash[hash]; - while (peer != 0 && peer->ass_next != peer_to_remove) - peer = peer->ass_next; - - if (peer == 0) { - assoc_hash_count[hash]++; - msyslog(LOG_ERR, - "peer struct for %s not in association table!", - stoa(&peer->srcadr)); - } else { - peer->ass_next = peer_to_remove->ass_next; - } + + UNLINK_SLIST(unlinked, assoc_hash[hash], peer_to_remove, + ass_next, struct peer); + + if (NULL == unlinked) { + assoc_hash_count[hash]++; + msyslog(LOG_ERR, + "peer struct for %s not in association table!", + stoa(&peer_to_remove->srcadr)); } - peer_to_remove->next = peer_free; - peer_free = peer_to_remove; + + LINK_SLIST(peer_free, peer_to_remove, next); peer_free_count++; } @@ -524,8 +504,13 @@ peer_config( * structures */ void -set_peerdstadr(struct peer *peer, struct interface *interface) +set_peerdstadr( + struct peer *peer, + struct interface *interface + ) { + struct peer *unlinked; + if (peer->dstadr != interface) { if (interface != NULL && (peer->cast_flags & MDF_BCLNT) && (interface->flags & INT_MCASTIF) && @@ -540,8 +525,8 @@ set_peerdstadr(struct peer *peer, struct interface *interface) } if (peer->dstadr != NULL) { peer->dstadr->peercnt--; - ISC_LIST_UNLINK_TYPE(peer->dstadr->peers, peer, - ilink, struct peer); + UNLINK_SLIST(unlinked, peer->dstadr->peers, + peer, ilink, struct peer); msyslog(LOG_INFO, "%s interface %s -> %s", stoa(&peer->srcadr), @@ -552,8 +537,7 @@ set_peerdstadr(struct peer *peer, struct interface *interface) } peer->dstadr = interface; if (peer->dstadr != NULL) { - ISC_LIST_APPEND(peer->dstadr->peers, peer, - ilink); + LINK_SLIST(peer->dstadr->peers, peer, ilink); peer->dstadr->peercnt++; } } @@ -759,9 +743,9 @@ newpeer( * actual interface, because that's what gets put into the peer * structure. */ - peer = findexistingpeer(srcadr, (struct peer *)0, hmode); - if (dstadr != 0) { - while (peer != 0) { + peer = findexistingpeer(srcadr, NULL, hmode); + if (dstadr != NULL) { + while (peer != NULL) { if (peer->dstadr == dstadr) break; @@ -787,13 +771,12 @@ newpeer( */ if (peer_free_count == 0) getmorepeermem(); - peer = peer_free; - peer_free = peer->next; + UNLINK_HEAD_SLIST(peer, peer_free, next); peer_free_count--; peer_associations++; if (flags & FLAG_PREEMPT) peer_preempt++; - memset((char *)peer, 0, sizeof(struct peer)); + memset(peer, 0, sizeof(*peer)); /* * Assign an association ID and increment the system variable. @@ -805,7 +788,6 @@ newpeer( DPRINTF(3, ("newpeer: cast flags: 0x%x for address: %s\n", cast_flags, stoa(srcadr))); - ISC_LINK_INIT(peer, ilink); /* set up interface link chain */ peer->srcadr = *srcadr; set_peerdstadr(peer, select_peerinterface(peer, srcadr, dstadr, cast_flags)); @@ -823,11 +805,11 @@ newpeer( if (minpoll == 0) peer->minpoll = NTP_MINDPOLL; else - peer->minpoll = min(minpoll, NTP_MAXPOLL); + peer->minpoll = (u_char)min(minpoll, NTP_MAXPOLL); if (maxpoll == 0) peer->maxpoll = NTP_MAXDPOLL; else - peer->maxpoll = max(maxpoll, NTP_MINPOLL); + peer->maxpoll = (u_char)max(maxpoll, NTP_MINPOLL); if (peer->minpoll > peer->maxpoll) peer->minpoll = peer->maxpoll; #ifdef DEBUG @@ -897,8 +879,7 @@ newpeer( * Dump it, something screwed up */ set_peerdstadr(peer, NULL); - peer->next = peer_free; - peer_free = peer; + LINK_SLIST(peer_free, peer, next); peer_free_count++; return (NULL); } @@ -909,12 +890,10 @@ newpeer( * Put the new peer in the hash tables. */ i = NTP_HASH_ADDR(&peer->srcadr); - peer->next = peer_hash[i]; - peer_hash[i] = peer; + LINK_SLIST(peer_hash[i], peer, next); peer_hash_count[i]++; i = peer->associd & NTP_HASH_MASK; - peer->ass_next = assoc_hash[i]; - assoc_hash[i] = peer; + LINK_SLIST(assoc_hash[i], peer, ass_next); assoc_hash_count[i]++; snprintf(tbuf, sizeof(tbuf), "assoc %d", peer->associd); report_event(PEVNT_MOBIL, peer, tbuf); diff --git a/ntpd/ntpd.c b/ntpd/ntpd.c index edefd582f6..b7be64afbd 100644 --- a/ntpd/ntpd.c +++ b/ntpd/ntpd.c @@ -543,16 +543,12 @@ ntpdmain( /* * Limit specific interfaces */ - init_specific_interface(); - if (HAVE_OPT( INTERFACE )) { int ifacect = STACKCT_OPT( INTERFACE ); const char** ifaces = STACKLST_OPT( INTERFACE ); - /* malloc space for the array of names */ - while (ifacect-- > 0) { + while (ifacect-- > 0) add_specific_interface(*ifaces++); - } } if (HAVE_OPT( NICE )) diff --git a/ports/winnt/libntp/libntp.dsp b/ports/winnt/libntp/libntp.dsp index a2106ef295..d8cb0ac009 100644 --- a/ports/winnt/libntp/libntp.dsp +++ b/ports/winnt/libntp/libntp.dsp @@ -522,6 +522,10 @@ SOURCE=..\..\..\include\ntp_lineedit.h # End Source File # Begin Source File +SOURCE=..\..\..\include\ntp_lists.h +# End Source File +# Begin Source File + SOURCE=..\..\..\include\ntp_machine.h # End Source File # Begin Source File diff --git a/ports/winnt/libntp/libntp.vcproj b/ports/winnt/libntp/libntp.vcproj index e8fd1fcc9d..53e349859a 100644 --- a/ports/winnt/libntp/libntp.vcproj +++ b/ports/winnt/libntp/libntp.vcproj @@ -1994,6 +1994,10 @@ RelativePath="..\..\..\include\ntp_lineedit.h" > + + diff --git a/ports/winnt/ntpd/ntp_iocompletionport.c b/ports/winnt/ntpd/ntp_iocompletionport.c index 97e341afa2..29c10c73b0 100644 --- a/ports/winnt/ntpd/ntp_iocompletionport.c +++ b/ports/winnt/ntpd/ntp_iocompletionport.c @@ -21,6 +21,7 @@ #include "ntp_assert.h" #include "clockstuff.h" #include "ntp_io.h" +#include "ntp_lists.h" #include "clockstuff.h" /* @@ -47,7 +48,7 @@ typedef struct IoCompletionInfo { transmitbuf_t * trans_buf; }; #ifdef DEBUG - ISC_LINK(struct IoCompletionInfo) link; + struct IoCompletionInfo *link; #endif } IoCompletionInfo; @@ -68,10 +69,10 @@ static int OnWriteComplete(ULONG_PTR, IoCompletionInfo *, DWORD, int); /* keep a list to traverse to free memory on debug builds */ #ifdef DEBUG static void free_io_completion_port_mem(void); -ISC_LIST(IoCompletionInfo) compl_info_list; -CRITICAL_SECTION compl_info_lock; -#define LOCK_COMPL() EnterCriticalSection(&compl_info_lock); -#define UNLOCK_COMPL() LeaveCriticalSection(&compl_info_lock); +IoCompletionInfo * compl_info_list; +CRITICAL_SECTION compl_info_lock; +#define LOCK_COMPL() EnterCriticalSection(&compl_info_lock); +#define UNLOCK_COMPL() LeaveCriticalSection(&compl_info_lock); #endif /* #define USE_HEAP */ @@ -110,7 +111,7 @@ GetHeapAlloc(char *fromfunc) #ifdef DEBUG LOCK_COMPL(); - ISC_LIST_APPEND(compl_info_list, lpo, link); + LINK_SLIST(compl_info_list, lpo, link); UNLOCK_COMPL(); #endif @@ -120,11 +121,14 @@ GetHeapAlloc(char *fromfunc) void FreeHeap(IoCompletionInfo *lpo, char *fromfunc) { +#ifdef DEBUG + IoCompletionInfo *unlinked; + DPRINTF(3, ("Freeing memory for %s, ptr %x\n", fromfunc, lpo)); -#ifdef DEBUG LOCK_COMPL(); - ISC_LIST_DEQUEUE(compl_info_list, lpo, link); + UNLINK_SLIST(unlinked, compl_info_list, lpo, link, + IoCompletionInfo); UNLOCK_COMPL(); #endif @@ -286,7 +290,6 @@ init_io_completion_port( HANDLE thread; #ifdef DEBUG - ISC_LIST_INIT(compl_info_list); InitializeCriticalSection(&compl_info_lock); atexit(&free_io_completion_port_mem); #endif @@ -363,9 +366,7 @@ free_io_completion_port_mem( IoCompletionInfo * pci; LOCK_COMPL(); - for (pci = ISC_LIST_HEAD(compl_info_list); - pci != NULL; - pci = ISC_LIST_HEAD(compl_info_list)) { + while ((pci = compl_info_list) != NULL) { /* this handles both xmit and recv buffs */ if (pci->recv_buf != NULL) @@ -392,7 +393,13 @@ uninit_io_completion_port( } -static int QueueSerialWait(struct refclockio *rio, recvbuf_t *buff, IoCompletionInfo *lpo, BOOL clear_timestamp) +static int +QueueSerialWait( + struct refclockio * rio, + recvbuf_t * buff, + IoCompletionInfo * lpo, + BOOL clear_timestamp + ) { lpo->request_type = SERIAL_WAIT; lpo->recv_buf = buff; diff --git a/ports/winnt/ntpd/ntpd.vcproj b/ports/winnt/ntpd/ntpd.vcproj index 3ec50c5a02..6178fe5e8e 100644 --- a/ports/winnt/ntpd/ntpd.vcproj +++ b/ports/winnt/ntpd/ntpd.vcproj @@ -483,6 +483,7 @@ Name="VCCLCompilerTool" AdditionalIncludeDirectories="" PreprocessorDefinitions="" + GeneratePreprocessedFile="0" /> @@ -847,6 +848,10 @@ RelativePath="..\include\ntp_iocompletionport.h" > + +