diff options
author | Eric S. Raymond <esr@thyrsus.com> | 2010-09-15 09:54:52 -0400 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 2010-09-15 09:54:52 -0400 |
commit | beebdc432d19aa4ffe029bda0b186706fa563aad (patch) | |
tree | 4dbf7af280451e40668e748606078d2bc7006e17 | |
parent | 318fed1131119802b4702c009f83177702742a4c (diff) | |
download | gpsd-beebdc432d19aa4ffe029bda0b186706fa563aad.tar.gz |
Switch TCP socket sources to nonblocking mode.
This follows a suggestion from Christian Eddie Dost <ecd@brainaid.de>,
who had this to say:
However, gpsd hangs when used with a tcp:// device, if you start the
device without waiting for clients (-n option), there will never be a
client connection accepted. If you start gpsd without -n option one
client will be accepted and receive data, but when closing the client
connection there will be no new connection possible.
The problem is gpsd hangs inside consume_packets() or more exactly
inside a blocking read() on the tcp socket a few functions further
down. consume_packets() never returns to the main select() loop.
The following patch configures sockets to non blocking, this fixes the
problem and gpsd works fine for me with tcp:// devices. Using this
patch should allow the special udp handling at the end of the function
consume_packets() to be removed.
I applied the suggested patch and also removed the special UDP
handing. All regressions test pass (including the UDP one), and gpsd
-N tcp://data.aishub.net:4006 reads AIS data as expected.
-rw-r--r-- | gpsd.c | 8 | ||||
-rw-r--r-- | netlib.c | 4 |
2 files changed, 4 insertions, 8 deletions
@@ -1493,14 +1493,6 @@ static void consume_packets(struct gps_device_t *device) } /*@+nullderef@*/ } /* subscribers */ - - /* - * Trying to read a nonexistent datagram hangs, - * so only go through the poll loop once after - * select in this case. - */ - if (device->sourcetype == source_udp) - break; } } @@ -34,6 +34,7 @@ #include <unistd.h> #endif /* S_SPLINT_S */ #include <string.h> +#include <fcntl.h> #include "gpsd.h" #include "sockaddr.h" @@ -138,6 +139,9 @@ socket_t netlib_connectsock(int af, const char *host, const char *service, setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof one); #endif + /* set socket to noblocking */ + fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK); + gpsd_report(LOG_SPIN, "netlib_connectsock() returns socket on fd %d\n", s); return s; |