]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Bug 1927] io_closeclock() should purge pending recvbufs.
authorDave Hart <hart@ntp.org>
Fri, 13 May 2011 21:38:33 +0000 (21:38 +0000)
committerDave Hart <hart@ntp.org>
Fri, 13 May 2011 21:38:33 +0000 (21:38 +0000)
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.

bk: 4dcda4d9YDoAXjjvbCKGsYNGly6c5g

ChangeLog
include/recvbuff.h
libntp/recvbuff.c
ntpd/ntp_io.c
ntpd/refclock_acts.c

index f74559804844ab18344323130cd62995631586ea..99d495be21b7604dd03c9efb3e334cf5e3f4cbda 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+* [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.
index 5f925f8ae86aa77005958206d4a38cf18d4eedaf..c73407db4ae28d4110409e6decd09a4d12c127e5 100644 (file)
@@ -24,7 +24,7 @@
 
 /*  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()     
@@ -76,11 +76,11 @@ struct recvbuf {
        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
@@ -88,29 +88,36 @@ extern      void    freerecvbuf (struct recvbuf *);
  *  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 */
index 2a8f046ee9221a65723d9b0eefb2f968961513f5..b7182252b527690dbdce9ce2502ea8cd6a8d7659 100644 (file)
@@ -160,7 +160,7 @@ freerecvbuf(recvbuf_t *rb)
        }
 
        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);
@@ -183,6 +183,7 @@ add_full_recv_buffer(recvbuf_t *rb)
        UNLOCK();
 }
 
+
 recvbuf_t *
 get_free_recv_buffer(void)
 {
@@ -200,6 +201,7 @@ get_free_recv_buffer(void)
        return (buffer);
 }
 
+
 #ifdef HAVE_IO_COMPLETION_PORT
 recvbuf_t *
 get_free_recv_buffer_alloc(void)
@@ -216,6 +218,7 @@ get_free_recv_buffer_alloc(void)
 }
 #endif
 
+
 recvbuf_t *
 get_full_recv_buffer(void)
 {
@@ -260,6 +263,37 @@ 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
  */
index 8aad2de20f9f03f09aa962e1c6f81ec401b700b3..f21e72fdf11f0350559247d7ee0585c566dc96d4 100644 (file)
@@ -3938,7 +3938,6 @@ io_addclock(
         * 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)) {
@@ -3955,7 +3954,7 @@ io_addclock(
        /*
         * enqueue
         */
-       refio = rio;
+       LINK_SLIST(refio, rio, next);
 
        /*
         * register fd
@@ -3966,6 +3965,7 @@ io_addclock(
        return 1;
 }
 
+
 /*
  * io_closeclock - close the clock in the I/O structure given
  */
@@ -3974,7 +3974,7 @@ io_closeclock(
        struct refclockio *rio
        )
 {
-       register struct refclockio *rp;
+       struct refclockio *unlinked;
 
        BLOCKIO();
 
@@ -3982,31 +3982,21 @@ io_closeclock(
         * 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
@@ -4038,6 +4028,7 @@ kill_asyncio(
 }
 #endif /* !SYS_WINNT */
 
+
 /*
  * Add and delete functions for the list of open sockets
  */
@@ -4056,6 +4047,7 @@ add_fd_to_list(
        maintain_activefds(fd, 0);
 }
 
+
 static void
 close_and_delete_fd_from_list(
        SOCKET fd
@@ -4093,6 +4085,7 @@ close_and_delete_fd_from_list(
        maintain_activefds(fd, 1);
 }
 
+
 static void
 add_addr_to_list(
        sockaddr_u *    addr,
index 05e8c6220eb96cc8101bde6247fac986c1de366f..9c2e178bd8c28bb2edaa50b511eae1be896a3223 100644 (file)
@@ -299,10 +299,7 @@ acts_shutdown(
         */
        pp = peer->procptr;
        up = pp->unitptr;
-       if (-1 != pp->io.fd) {
-               io_closeclock(&pp->io);
-               pp->io.fd = -1;
-       }
+       acts_close(peer);
        free(up);
 }
 
@@ -318,8 +315,9 @@ acts_receive(
        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
@@ -331,13 +329,13 @@ acts_receive(
        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;
@@ -606,7 +604,7 @@ acts_close(
 
        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);