From: Juergen Perlinger Date: Thu, 9 Feb 2012 22:18:03 +0000 (+0100) Subject: [Bug 2135] defer calls to 'io_input' to main thread under Windows X-Git-Tag: NTP_4_2_7P257~2^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6c7fe74e7df3fd64c89c3059012dc6ecbe26bbb6;p=thirdparty%2Fntp.git [Bug 2135] defer calls to 'io_input' to main thread under Windows bk: 4f34461bu6Jag4QBwDIBWKfIusAyXA --- diff --git a/ChangeLog b/ChangeLog index 41f87f234..8c622a1c9 100644 --- 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 * [Bug 603] Only link with nlist()-related libraries when needed: More cleanup. diff --git a/include/ntp_refclock.h b/include/ntp_refclock.h index 86e8b34fb..b168d243c 100644 --- a/include/ntp_refclock.h +++ b/include/ntp_refclock.h @@ -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 */ diff --git a/ntpd/ntp_refclock.c b/ntpd/ntp_refclock.c index 4c6733c09..43b736aac 100644 --- a/ntpd/ntp_refclock.c +++ b/ntpd/ntp_refclock.c @@ -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 ... */ diff --git a/ntpd/refclock_msfees.c b/ntpd/refclock_msfees.c index f34327558..89b4aa819 100644 --- a/ntpd/refclock_msfees.c +++ b/ntpd/refclock_msfees.c @@ -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)) diff --git a/ntpd/refclock_parse.c b/ntpd/refclock_parse.c index df8bfe217..157753e38 100644 --- a/ntpd/refclock_parse.c +++ b/ntpd/refclock_parse.c @@ -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); diff --git a/ports/winnt/ntpd/ntp_iocompletionport.c b/ports/winnt/ntpd/ntp_iocompletionport.c index aca633722..ae59486fe 100644 --- a/ports/winnt/ntpd/ntp_iocompletionport.c +++ b/ports/winnt/ntpd/ntp_iocompletionport.c @@ -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(); }