diff options
author | Eric S. Raymond <esr@thyrsus.com> | 2015-02-02 01:30:08 -0500 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 2015-02-02 01:30:08 -0500 |
commit | e9b32d194285e307630f6e3cf64587976acde8bb (patch) | |
tree | c9141142b9757bfde82194c8245ae83f40e2f697 /serial.c | |
parent | 71d21c1566cd6ab0cc5d66b5d551faec521735d7 (diff) | |
download | gpsd-e9b32d194285e307630f6e3cf64587976acde8bb.tar.gz |
Change to using blocking I/O and VTIME.
This addresses the buzzing-select problem, but the cost is that the GPS
regression tests require longer delays and may hang if the delays are too short.
All regression tests pass.
Diffstat (limited to 'serial.c')
-rw-r--r-- | serial.c | 24 |
1 files changed, 4 insertions, 20 deletions
@@ -450,7 +450,7 @@ int gpsd_serial_open(struct gps_device_t *session) "bluetooth socket connect in progress or again : %s\n", strerror(errno)); } - (void)fcntl(session->gpsdata.gps_fd, F_SETFL, (int)mode | O_NONBLOCK); + (void)fcntl(session->gpsdata.gps_fd, F_SETFL, (int)mode); gpsd_report(&session->context->errout, LOG_PROG, "bluez device open success: %s %s\n", session->gpsdata.dev.path, strerror(errno)); @@ -459,13 +459,13 @@ int gpsd_serial_open(struct gps_device_t *session) { if ((session->gpsdata.gps_fd = open(session->gpsdata.dev.path, - (int)(mode | O_NONBLOCK | O_NOCTTY))) == -1) { + (int)(mode | O_NOCTTY))) == -1) { gpsd_report(&session->context->errout, LOG_ERROR, "device open failed: %s - retrying read-only\n", strerror(errno)); if ((session->gpsdata.gps_fd = open(session->gpsdata.dev.path, - O_RDONLY | O_NONBLOCK | O_NOCTTY)) == -1) { + O_RDONLY | O_NOCTTY)) == -1) { gpsd_report(&session->context->errout, LOG_ERROR, "read-only device open failed: %s\n", strerror(errno)); @@ -533,25 +533,9 @@ int gpsd_serial_open(struct gps_device_t *session) return -1; (void)memcpy(&session->ttyset, &session->ttyset_old, sizeof(session->ttyset)); - /* - * Only block until we get at least one character, whatever the - * third arg of read(2) says. According to - * http://stackoverflow.com/questions/20154157/termios-vmin-vtime-and-blocking-non-blocking-read-operations - * the VMIN setting may be a no-op because the tty was opened with - * O_NONBLOCK. Money quote: - * - * "When using select() with a file in non-blocking mode, you - * get an event for every byte that arrives. At high serial - * data rates, this hammers the CPU. It's better to use - * blocking mode with VMIN, so that select() waits for a - * block of data before firing an event, and VTIME to limit - * the delay, for blocks smaller than VMIN." - * - * Would that we could do the latter... - */ /*@ ignore @*/ memset(session->ttyset.c_cc, 0, sizeof(session->ttyset.c_cc)); - session->ttyset.c_cc[VMIN] = 1; + session->ttyset.c_cc[VTIME] = 1; /*@ end @*/ /* * Tip from Chris Kuethe: the FIDI chip used in the Trip-Nav |