+* [Bug 1927] io_closeclock() should purge pending recvbufs.
+* Use acts_close() in acts_shutdown() to avoid leaving a stale lockfile
+ if unpeered via runtime configuration while the modem is open.
+* Correct acts_close() test of pp->io.fd to see if it is open.
(4.2.7p166) 2011/05/13 Released by Harlan Stenn <stenn@ntp.org>
* If we have local overrides for autogen template files, use them.
* Convert more of the sntp-opt.def documentation from man to mdoc.
/* Return the event which is set when items are added to the full list
*/
-extern HANDLE get_recv_buff_event (void);
+extern HANDLE get_recv_buff_event(void);
#else
# define RECV_BLOCK_IO()
# define RECV_UNBLOCK_IO()
int used; /* reference count */
};
-extern void init_recvbuff (int);
+extern void init_recvbuff(int);
/* freerecvbuf - make a single recvbuf available for reuse
*/
-extern void freerecvbuf (struct recvbuf *);
+extern void freerecvbuf(struct recvbuf *);
/* Get a free buffer (typically used so an async
* read can directly place data into the buffer
* The buffer is removed from the free list. Make sure
* you put it back with freerecvbuf() or
*/
-extern struct recvbuf *get_free_recv_buffer (void); /* signal safe - no malloc */
-extern struct recvbuf *get_free_recv_buffer_alloc (void); /* signal unsafe - may malloc */
+
+/* signal safe - no malloc */
+extern struct recvbuf *get_free_recv_buffer(void);
+/* signal unsafe - may malloc */
+extern struct recvbuf *get_free_recv_buffer_alloc(void);
/* Add a buffer to the full list
*/
-extern void add_full_recv_buffer (struct recvbuf *);
-
-/*extern void process_recv_buffers (void); */
+extern void add_full_recv_buffer(struct recvbuf *);
/* number of recvbufs on freelist */
-extern u_long free_recvbuffs (void);
-extern u_long full_recvbuffs (void);
-extern u_long total_recvbuffs (void);
-extern u_long lowater_additions (void);
+extern u_long free_recvbuffs(void);
+extern u_long full_recvbuffs(void);
+extern u_long total_recvbuffs(void);
+extern u_long lowater_additions(void);
/* Returns the next buffer in the full list.
*
*/
-extern struct recvbuf *get_full_recv_buffer (void);
+extern struct recvbuf *get_full_recv_buffer(void);
+
+/*
+ * purge_recv_buffers_for_fd() - purges any previously-received input
+ * from a given file descriptor.
+ */
+extern void purge_recv_buffers_for_fd(SOCKET);
/*
* Checks to see if there are buffers to process
*/
-extern isc_boolean_t has_full_recv_buffer (void);
+extern isc_boolean_t has_full_recv_buffer(void);
#endif /* RECVBUFF_H */
}
LOCK();
- (rb->used)--;
+ rb->used--;
if (rb->used != 0)
msyslog(LOG_ERR, "******** freerecvbuff non-zero usage: %d *******", rb->used);
LINK_SLIST(free_recv_list, rb, link.next);
UNLOCK();
}
+
recvbuf_t *
get_free_recv_buffer(void)
{
return (buffer);
}
+
#ifdef HAVE_IO_COMPLETION_PORT
recvbuf_t *
get_free_recv_buffer_alloc(void)
}
#endif
+
recvbuf_t *
get_full_recv_buffer(void)
{
return rbuf;
}
+
+/*
+ * purge_recv_buffers_for_fd() - purges any previously-received input
+ * from a given file descriptor.
+ */
+void
+purge_recv_buffers_for_fd(
+ SOCKET fd
+ )
+{
+ recvbuf_t *rbufp;
+ recvbuf_t *next;
+
+ LOCK();
+
+ for (rbufp = ISC_LIST_HEAD(full_recv_list);
+ rbufp != NULL;
+ rbufp = next) {
+ next = ISC_LIST_NEXT(rbufp, link);
+ if (rbufp->fd == fd) {
+ ISC_LIST_DEQUEUE_TYPE(full_recv_list, rbufp,
+ link, recvbuf_t);
+ full_recvbufs--;
+ freerecvbuf(rbufp);
+ }
+ }
+
+ UNLOCK();
+}
+
+
/*
* Checks to see if there are buffers to process
*/
* in use. There is a harmless (I hope) race condition here.
*/
rio->active = TRUE;
- rio->next = refio;
# ifdef HAVE_SIGNALED_IO
if (init_clock_sig(rio)) {
/*
* enqueue
*/
- refio = rio;
+ LINK_SLIST(refio, rio, next);
/*
* register fd
return 1;
}
+
/*
* io_closeclock - close the clock in the I/O structure given
*/
struct refclockio *rio
)
{
- register struct refclockio *rp;
+ struct refclockio *unlinked;
BLOCKIO();
* Remove structure from the list
*/
rio->active = FALSE;
- if (refio == rio)
- refio = rio->next;
- else {
- for (rp = refio; rp != NULL; rp = rp->next)
- if (rp->next == rio) {
- rp->next = rio->next;
- break;
- }
-
- if (NULL == rp) {
- UNBLOCKIO();
- return;
- }
+ UNLINK_SLIST(unlinked, refio, rio, next, struct refclockio);
+ if (NULL != unlinked) {
+ purge_recv_buffers_for_fd(rio->fd);
+ /*
+ * Close the descriptor.
+ */
+ close_and_delete_fd_from_list(rio->fd);
}
- rio->next = NULL;
-
- /*
- * Close the descriptor.
- */
- close_and_delete_fd_from_list(rio->fd);
rio->fd = -1;
+
UNBLOCKIO();
}
#endif /* REFCLOCK */
+
/*
* On NT a SOCKET is an unsigned int so we cannot possibly keep it in
* an array. So we use one of the ISC_LIST functions to hold the
}
#endif /* !SYS_WINNT */
+
/*
* Add and delete functions for the list of open sockets
*/
maintain_activefds(fd, 0);
}
+
static void
close_and_delete_fd_from_list(
SOCKET fd
maintain_activefds(fd, 1);
}
+
static void
add_addr_to_list(
sockaddr_u * addr,
*/
pp = peer->procptr;
up = pp->unitptr;
- if (-1 != pp->io.fd) {
- io_closeclock(&pp->io);
- pp->io.fd = -1;
- }
+ acts_close(peer);
free(up);
}
struct actsunit *up;
struct refclockproc *pp;
struct peer *peer;
- char tbuf[BMAX];
- char *tptr;
+ char tbuf[sizeof(up->buf)];
+ char * tptr;
+ int octets;
/*
* Initialize pointers and read the timecode and timestamp. Note
peer = rbufp->recv_peer;
pp = peer->procptr;
up = pp->unitptr;
- refclock_gtraw(rbufp, tbuf, BMAX - (up->bufptr - up->buf), &pp->lastrec);
+ octets = sizeof(up->buf) - (up->bufptr - up->buf);
+ refclock_gtraw(rbufp, tbuf, octets, &pp->lastrec);
for (tptr = tbuf; *tptr != '\0'; tptr++) {
if (*tptr == LF) {
if (up->bufptr == up->buf) {
up->tstamp = pp->lastrec;
continue;
-
} else {
*up->bufptr = '\0';
up->bufptr = up->buf;
pp = peer->procptr;
up = pp->unitptr;
- if (pp->io.fd != 0) {
+ if (pp->io.fd != -1) {
report_event(PEVNT_CLOCK, peer, "close");
dtr = TIOCM_DTR;
ioctl(pp->io.fd, TIOCMBIC, &dtr);