doubly-linked lists to singly-linked.
bk: 4a5f5409mcVB8S7OBSMxwMH2aza67w
+* [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 <stenn@ntp.org>
* Documentation updates from Dave Mills.
* [Bug 1234] convert NMEA driver to use common PPSAPI code.
#include <ntp_net.h>
#include <isc/boolean.h>
-#include <isc/list.h>
/*
* Calendar arithmetic - contributed by G. Healton
* 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 */
};
/*
* 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 */
-#if !defined _NTP_IO_H
-#define _NTP_IO_H
+#ifndef NTP_IO_H
+#define NTP_IO_H
/*
* POSIX says use <fnct.h> to get O_* symbols and
* SEEK_SET symbol form <unistd.h>.
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 */
--- /dev/null
+/*
+ * 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 <config.h>
+#endif
+
+#include <isc/list.h>
+
+
+#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 */
-#if !defined __recvbuff_h
-#define __recvbuff_h
+#ifndef RECVBUFF_H
+#define RECVBUFF_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#include "ntp.h"
#include "ntp_fp.h"
+#include "ntp_lists.h"
-#include <isc/list.h>
#include <isc/result.h>
/*
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;
*/
extern isc_boolean_t has_full_recv_buffer (void);
-#endif /* defined __recvbuff_h */
-
+#endif /* RECVBUFF_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>
#ifdef DEBUG
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)
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++;
* 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;
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 */
(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();
}
return;
}
LOCK();
+ ISC_LINK_INIT(rb, link);
ISC_LIST_APPEND(full_recv_list, 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.next);
+ if (buffer != NULL) {
free_recvbufs--;
initialise_buffer(buffer);
(buffer->used)++;
- }
- else
- {
+ } else
buffer_shortfall++;
- }
UNLOCK();
return (buffer);
}
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
#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
*/
* 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);
}
#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"
/* Don't include ISC's version of IPv6 variables and structures */
#define ISC_IPV6_H 1
#include <isc/interfaceiter.h>
-#include <isc/list.h>
#include <isc/netaddr.h>
#include <isc/result.h>
#include <isc/sockaddr.h>
*/
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)
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)
* 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);
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;
(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
*/
reader = emalloc(sizeof(*reader));
memset(reader, 0, sizeof(*reader));
- ISC_LINK_INIT(reader, link);
reader->fd = INVALID_SOCKET;
return 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);
}
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);
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
*/
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);
}
/*
)
{
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);
- }
}
/*
)
{
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;
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++;
}
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);
* 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);
/*
* 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);
struct interface interface;
struct interface * iface;
struct interface * next;
- struct peer * peer;
DPRINTF(3, ("update_interfaces(%d)\n", port));
* 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))) {
/*
* 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
#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;
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;
{
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;
/*
* 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)
/*
* 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 */
|| 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)
* 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;
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();
}
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
*/
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
}
}
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)));
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);
+ }
}
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);
}
}
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;
}
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)) {
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) {
#include <sys/types.h>
#include "ntpd.h"
+#include "ntp_lists.h"
#include "ntp_stdlib.h"
#include "ntp_control.h"
#include <ntp_random.h>
/*
* 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.
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
/*
* 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;
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++;
}
struct peer *peer_to_remove
)
{
+ register struct peer *unlinked;
int hash;
char tbuf[80];
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));
}
/*
*/
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++;
}
* 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) &&
}
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),
}
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++;
}
}
* 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;
*/
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.
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));
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
* 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);
}
* 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);
/*
* 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 ))
# 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
RelativePath="..\..\..\include\ntp_lineedit.h"
>
</File>
+ <File
+ RelativePath="..\..\..\include\ntp_lists.h"
+ >
+ </File>
<File
RelativePath="..\..\..\include\ntp_machine.h"
>
#include "ntp_assert.h"
#include "clockstuff.h"
#include "ntp_io.h"
+#include "ntp_lists.h"
#include "clockstuff.h"
/*
transmitbuf_t * trans_buf;
};
#ifdef DEBUG
- ISC_LINK(struct IoCompletionInfo) link;
+ struct IoCompletionInfo *link;
#endif
} IoCompletionInfo;
/* 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 */
#ifdef DEBUG
LOCK_COMPL();
- ISC_LIST_APPEND(compl_info_list, lpo, link);
+ LINK_SLIST(compl_info_list, lpo, link);
UNLOCK_COMPL();
#endif
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
HANDLE thread;
#ifdef DEBUG
- ISC_LIST_INIT(compl_info_list);
InitializeCriticalSection(&compl_info_lock);
atexit(&free_io_completion_port_mem);
#endif
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)
}
-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;
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
+ GeneratePreprocessedFile="0"
/>
</FileConfiguration>
</File>
RelativePath="..\include\ntp_iocompletionport.h"
>
</File>
+ <File
+ RelativePath="..\..\..\include\ntp_lists.h"
+ >
+ </File>
<File
RelativePath="..\..\..\include\ntp_machine.h"
>