]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Bug 2135] defer calls to 'io_input' to main thread under Windows
authorJuergen Perlinger <perlinger@ntp.org>
Thu, 9 Feb 2012 22:18:03 +0000 (23:18 +0100)
committerJuergen Perlinger <perlinger@ntp.org>
Thu, 9 Feb 2012 22:18:03 +0000 (23:18 +0100)
bk: 4f34461bu6Jag4QBwDIBWKfIusAyXA

ChangeLog
include/ntp_refclock.h
ntpd/ntp_refclock.c
ntpd/refclock_msfees.c
ntpd/refclock_parse.c
ports/winnt/ntpd/ntp_iocompletionport.c

index 41f87f234d82fa29e6d46db66a5bb47ed673750d..8c622a1c9fc9d7871f80e064ed5fd7316748aadc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,4 @@
+* [Bug 2135] defer calls to 'io_input' to main thread under Windows
 (4.2.7p255) 2012/01/29 Released by Harlan Stenn <stenn@ntp.org>
 * [Bug 603] Only link with nlist()-related libraries when needed:
   More cleanup.
index 86e8b34fbca89cb9c7ae047ae8159e649c6e09b0..b168d243cf1a081174436652d2f9569600efdac6 100644 (file)
@@ -229,6 +229,7 @@ extern      int     refclock_gtlin  (struct recvbuf *, char *, int, l_fp *);
 extern int     refclock_gtraw  (struct recvbuf *, char *, int, l_fp *);
 extern int     indicate_refclock_packet(struct refclockio *,
                                         struct recvbuf *);
+extern void    process_refclock_packet(struct recvbuf *);
 #endif /* REFCLOCK */
 
 #endif /* NTP_REFCLOCK_H */
index 4c6733c095411f6e7b2e21c0c7b494c983062b68..43b736aacf16fb19181256a3e8a4372e8c4d79a2 100644 (file)
@@ -265,7 +265,6 @@ refclock_timer(
        )
 {
        struct refclockproc *   pp;
-       u_char                  clktype;
        int                     unit;
 
        unit = p->refclkunit;
@@ -581,25 +580,37 @@ refclock_gtlin(
        l_fp    *tsptr          /* pointer to timestamp returned */
        )
 {
-       char    s[BMAX];
-       char    *dpt, *dpend, *dp;
+       const char *sp, *spend;
+       char       *dp, *dpend;
+       int         dlen;
 
-       dpt = s;
-       dpend = s + refclock_gtraw(rbufp, s, BMAX - 1, tsptr);
-       if (dpend - dpt > bmax - 1)
-               dpend = dpt + bmax - 1;
-       for (dp = lineptr; dpt < dpend; dpt++) {
-               char    c;
+       if (bmax <= 0)
+               return (0);
+
+       dp    = lineptr;
+       dpend = dp + bmax - 1; /* leave room for NUL pad */
+       sp    = (const char *)rbufp->recv_buffer;
+       spend = sp + rbufp->recv_length;
 
-               c = *dpt & 0x7f;
+       while (sp != spend && dp != dpend) {
+               char c;
+               
+               c = *sp++ & 0x7f;
                if (c >= 0x20 && c < 0x7f)
                        *dp++ = c;
        }
-       if (dp == lineptr)
-               return (0);
-
-       *dp = '\0';
-       return (dp - lineptr);
+       /* Get length of data written to the destination buffer. If
+        * zero, do *not* place a NUL byte to preserve the previous
+        * buffer content.
+        */
+       dlen = dp - lineptr;
+       if (dlen)
+           *dp  = '\0';
+       *tsptr = rbufp->recv_time;
+       DPRINTF(2, ("refclock_gtlin: fd %d time %s timecode %d %s\n",
+                   rbufp->fd, ulfptoa(&rbufp->recv_time, 6), dlen,
+                   lineptr));
+       return (dlen);
 }
 
 
@@ -626,27 +637,19 @@ refclock_gtraw(
        l_fp    *tsptr          /* pointer to timestamp returned */
        )
 {
-       char    *dpt, *dpend, *dp;
-       int     i;
-
-       dpt = (char *)rbufp->recv_buffer;
-       dpend = dpt + rbufp->recv_length;
+       if (bmax <= 0)
+               return (0);
+       bmax -= 1; /* leave room for trailing NUL */
+       if (bmax > rbufp->recv_length)
+               bmax = rbufp->recv_length;
+       memcpy(lineptr, rbufp->recv_buffer, bmax);
+       lineptr[bmax] = '\0';
 
-       /*
-        * Copy the raw buffer to the user string. The string is padded
-        * with a NUL, which is not included in the character count.
-        */
-       if (dpend - dpt > bmax - 1)
-               dpend = dpt + bmax - 1;
-       for (dp = lineptr; dpt < dpend; dpt++)
-               *dp++ = *dpt;
-       *dp = '\0';
-       i = dp - lineptr;
        *tsptr = rbufp->recv_time;
        DPRINTF(2, ("refclock_gtraw: fd %d time %s timecode %d %s\n",
-                   rbufp->fd, ulfptoa(&rbufp->recv_time, 6), i,
+                   rbufp->fd, ulfptoa(&rbufp->recv_time, 6), bmax,
                    lineptr));
-       return (i);
+       return (bmax);
 }
 
 
@@ -685,6 +688,36 @@ indicate_refclock_packet(
 }
 
 
+/*
+ * process_refclock_packet()
+ *
+ * Used for deferred processing of 'io_input' on systems where threading
+ * is used (notably Windows). This is acting as a trampoline to make the
+ * real calls to the refclock functions.
+ */
+void
+process_refclock_packet(
+       struct recvbuf * rb
+       )
+{
+       struct refclockio * rio;
+
+       /* get the refclockio structure from the receive buffer */
+       rio  = &rb->recv_peer->procptr->io;
+
+       /* call 'clock_recv' if either there is no input function or the
+        * raw input function tells us to feed the packet to the
+        * receiver.
+        */
+       if (rio->io_input == NULL || (*rio->io_input)(rb) != 0) {
+               rio->recvcount++;
+               packets_received++;
+               handler_pkts++;         
+               (*rio->clock_recv)(rb);
+       }
+}
+
+
 /*
  * The following code does not apply to WINNT & VMS ...
  */
index f34327558ed3b2cd0cb25035c51fc0bfa90c1d2b..89b4aa819ce0f7f41d428655c1e5569a836721be 100644 (file)
@@ -534,7 +534,7 @@ msfees_start(
        ees->timestarted= current_time;
        ees->ttytype    = 0;
        ees->io.clock_recv= ees_receive;
-       ees->io.srcclock= ees;
+       ees->io.srcclock= peer;
        ees->io.datalen = 0;
        ees->io.fd      = fd232;
 
@@ -674,7 +674,7 @@ ees_receive(
 #endif
 
        /* Get the clock this applies to and a pointer to the data */
-       ees = (struct eesunit *)rbufp->recv_srcclock;
+       ees = (struct eesunit *)rbufp->recv_peer->procptr->unitptr;
        dpt = (u_char *)&rbufp->recv_space;
        dpend = dpt + rbufp->recv_length;
        if ((dbg & DB_LOG_AWAITMORE) && (rbufp->recv_length != LENEESCODE))
index df8bfe217daf35e4825185909461acffedd5792d..157753e38b264de738829b1a06c76fc2122b4bc6 100644 (file)
@@ -1967,9 +1967,9 @@ stream_receive(
        struct recvbuf *rbufp
        )
 {
-       struct parseunit *parse = (struct parseunit *)((void *)rbufp->recv_srcclock);
-       parsetime_t parsetime;
+       struct parseunit * parse;
 
+       parse = (struct parseunit *)rbufp->recv_peer->procptr->unitptr;
        if (!parse->peer)
            return;
 
@@ -2115,11 +2115,13 @@ local_input(
        struct recvbuf *rbufp
        )
 {
-       struct parseunit *parse = (struct parseunit *)((void *)rbufp->recv_srcclock);
+       struct parseunit * parse;
+
        int count;
        unsigned char *s;
        timestamp_t ts;
 
+       parse = (struct parseunit *)rbufp->recv_peer->procptr->unitptr;
        if (!parse->peer)
                return 0;
 
@@ -2332,9 +2334,10 @@ local_receive(
        struct recvbuf *rbufp
        )
 {
-       struct parseunit *parse = (struct parseunit *)((void *)rbufp->recv_srcclock);
+       struct parseunit * parse;
        parsetime_t parsetime;
 
+       parse = (struct parseunit *)rbufp->recv_peer->procptr->unitptr;
        if (!parse->peer)
            return;
 
@@ -3129,7 +3132,7 @@ parse_start(
        /*
         * pick correct input machine
         */
-       parse->generic->io.srcclock = (void *)parse;
+       parse->generic->io.srcclock = peer;
        parse->generic->io.datalen = 0;
        
        parse->binding = init_iobinding(parse);
index aca63372239434635a0cc5758dae33e6ae55b96b..ae59486fec4a5957b2f73e4350efd1d13583eb9c 100644 (file)
@@ -584,7 +584,7 @@ OnSerialReadComplete(
         */
        if (!errstatus && Bytes) {
                buff->recv_length = (int) Bytes;
-               buff->receiver = rio->clock_recv;
+               buff->receiver = process_refclock_packet;
                buff->dstadr = NULL;
                buff->recv_peer = rio->srcclock;
                /*
@@ -609,14 +609,11 @@ OnSerialReadComplete(
                        buff->recv_time = cr_time;
                        buff->recv_length = 0;
                        buff->fd = rio->fd;
-                       buff->receiver = rio->clock_recv;
+                       buff->receiver = process_refclock_packet;
                        buff->dstadr = NULL;
                        buff->recv_peer = rio->srcclock;
-                       consumed = indicate_refclock_packet(rio, buff);
-                       if (!consumed) {
-                               packets_received++;
-                               handler_pkts++;
-                       }
+                       add_full_recv_buffer(buff);
+                       SetEvent(WaitableIoEventHandle);
                        buff = get_free_recv_buffer_alloc();
                }
        }
@@ -678,16 +675,12 @@ OnRawSerialReadComplete(
                rbufp->recv_length = (int)octets;
                rbufp->dstadr = NULL;
                rbufp->recv_time = arrival_time;
-               rbufp->receiver = rio->clock_recv;
+               rbufp->receiver = process_refclock_packet;
                rbufp->recv_peer = rio->srcclock;
                rbufp->fd = rio->fd; /* was handle */
 
-               consumed = indicate_refclock_packet(rio, rbufp);
-               if (!consumed) {
-                       rio->recvcount++;
-                       packets_received++;
-                       handler_pkts++;
-               }
+               add_full_recv_buffer(rbufp);
+               SetEvent(WaitableIoEventHandle);
                rbufp = get_free_recv_buffer_alloc();
        }