From db993006c341f476e80cf7f1aba59081d2947ab3 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Mon, 3 Oct 2011 10:45:29 -0400 Subject: First cut at implementing waiting test for shm export. Timeout argument is presently ignored. --- libgps.h | 6 +++--- libgps.xml | 2 +- libgps_core.c | 8 +++++++- libgps_shm.c | 14 ++++++++++++++ shmexport.c | 5 +++-- 5 files changed, 28 insertions(+), 7 deletions(-) diff --git a/libgps.h b/libgps.h index 5901ea89..cc5b5e70 100644 --- a/libgps.h +++ b/libgps.h @@ -37,12 +37,12 @@ extern int gps_sock_stream(struct gps_data_t *, unsigned int, /*@null@*/void *); extern const char /*@observer@*/ *gps_sock_data(const struct gps_data_t *); extern int gps_sock_mainloop(struct gps_data_t *, int, void (*)(struct gps_data_t *)); -extern int gps_shm_mainloop(struct gps_data_t *, int, - void (*)(struct gps_data_t *)); - extern int gps_shm_open(/*@out@*/struct gps_data_t *); extern void gps_shm_close(struct gps_data_t *); +extern bool gps_shm_waiting(const struct gps_data_t *, int); extern int gps_shm_read(struct gps_data_t *); +extern int gps_shm_mainloop(struct gps_data_t *, int, + void (*)(struct gps_data_t *)); extern int gps_dbus_open(struct gps_data_t *); extern int gps_dbus_mainloop(struct gps_data_t *, int, diff --git a/libgps.xml b/libgps.xml index 059c7d01..2f5d09d5 100644 --- a/libgps.xml +++ b/libgps.xml @@ -150,7 +150,7 @@ error condition. This function is a convenience wrapper around a select2 call, and zeros errno on entry; you can test errno after exit to get more information about -error conditions. +error conditions. The timeout value is in nanoseconds. gps_unpack() parses JSON from the argument buffer into the target of the session structure pointer argument. diff --git a/libgps_core.c b/libgps_core.c index 1759e6a5..687b8b82 100644 --- a/libgps_core.c +++ b/libgps_core.c @@ -205,8 +205,14 @@ bool gps_waiting(const struct gps_data_t *gpsdata CONDITIONALLY_UNUSED, int time /* this is bogus, but I can't think of a better solution yet */ bool waiting = true; +#ifdef SHM_EXPORT_ENABLE + if ((intptr_t)(gpsdata->gps_fd) == SHM_PSEUDO_FD) + waiting = gps_shm_waiting(gpsdata, timeout); +#endif /* SHM_EXPORT_ENABLE */ + #ifdef SOCKET_EXPORT_ENABLE - waiting = gps_sock_waiting(gpsdata, timeout); + if ((intptr_t)(gpsdata->gps_fd) >= 0) + waiting = gps_sock_waiting(gpsdata, timeout); #endif /* SOCKET_EXPORT_ENABLE */ return waiting; diff --git a/libgps_shm.c b/libgps_shm.c index b28b13a7..1ea25c67 100644 --- a/libgps_shm.c +++ b/libgps_shm.c @@ -31,6 +31,7 @@ PERMISSIONS struct privdata_t { void *shmseg; + int tick; }; /*@+matchfields@*/ @@ -65,6 +66,18 @@ int gps_shm_open(/*@out@*/struct gps_data_t *gpsdata) return 0; } +bool gps_shm_waiting(const struct gps_data_t *gpsdata, int timeout UNUSED) +/* check to see if new dayta has been written */ +{ + volatile struct shmexport_t *shared = (struct shmexport_t *)PRIVATE(gpsdata)->shmseg; + bool newdata; + + barrier(); + newdata = (shared->bookend1 == shared->bookend2 && shared->bookend1 > PRIVATE(gpsdata)->tick + timeout); + barrier(); + return newdata; +} + int gps_shm_read(struct gps_data_t *gpsdata) /* read an update from the shared-memory segment */ { @@ -104,6 +117,7 @@ int gps_shm_read(struct gps_data_t *gpsdata) (void *)&noclobber, sizeof(struct gps_data_t)); /*@i1@*/gpsdata->privdata = private_save; + PRIVATE(gpsdata)->tick = after; if ((gpsdata->set & REPORT_IS)!=0) { if (gpsdata->fix.mode >= 2) gpsdata->status = STATUS_FIX; diff --git a/shmexport.c b/shmexport.c index 8e2cf190..5959b581 100644 --- a/shmexport.c +++ b/shmexport.c @@ -22,6 +22,7 @@ PERMISSIONS #include #include "gpsd.h" +#include "libgps.h" /* for SHM_PSEUDO_FD */ #ifdef SHM_EXPORT_ENABLE @@ -84,9 +85,9 @@ void shm_update(struct gps_context_t *context, struct gps_data_t *gpsdata) sizeof(struct gps_data_t)); barrier(); #ifndef USE_QT - shared->gpsdata.gps_fd = -1; + shared->gpsdata.gps_fd = SHM_PSEUDO_FD; #else - shared->gpsdata.gps_fd = (void *)(intptr_t)-1; + shared->gpsdata.gps_fd = (void *)(intptr_t)SHM_PSEUDO_FD; #endif /* USE_QT */ barrier(); shared->bookend1 = tick; -- cgit v1.2.1