diff options
author | Eric S. Raymond <esr@thyrsus.com> | 2015-03-06 14:39:18 -0500 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 2015-03-06 14:39:18 -0500 |
commit | 527d0f52feb0f0d48967dbd7b7580cce18fbdbe7 (patch) | |
tree | 0c25c23b72e8e2877b7e0ee94088a99a39ff7a43 /libgps_shm.c | |
parent | b852278f33d6b280eed4107301e73ece96080ee5 (diff) | |
download | gpsd-527d0f52feb0f0d48967dbd7b7580cce18fbdbe7.tar.gz |
Insert memory barriers in libgps_shm_waiting().
Also, make sure it reurns false on timeout.
All regression tests pass.
Diffstat (limited to 'libgps_shm.c')
-rw-r--r-- | libgps_shm.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/libgps_shm.c b/libgps_shm.c index f55877bf..dc9bcc2c 100644 --- a/libgps_shm.c +++ b/libgps_shm.c @@ -77,19 +77,23 @@ bool gps_shm_waiting(const struct gps_data_t *gpsdata, int timeout) { volatile struct shmexport_t *shared = (struct shmexport_t *)PRIVATE(gpsdata)->shmseg; timestamp_t basetime = timestamp(); + volatile bool newdata = false; /* busy-waiting sucks, but there's not really an alternative */ for (;;) { - bool newdata = false; + volatile int bookend1, bookend2; memory_barrier(); - if (shared->bookend1 == shared->bookend2 && shared->bookend1 > PRIVATE(gpsdata)->tick) - newdata = true; + bookend1 = shared->bookend1; + memory_barrier(); + bookend2 = shared->bookend2; memory_barrier(); + if (bookend1 == bookend2 && bookend1 > PRIVATE(gpsdata)->tick) + newdata = true; if (newdata || (timestamp() - basetime >= (double)timeout)) break; } - return true; + return newdata; } int gps_shm_read(struct gps_data_t *gpsdata) |