diff options
author | Eric S. Raymond <esr@thyrsus.com> | 2011-03-26 01:42:09 -0400 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 2011-03-26 01:42:09 -0400 |
commit | de697118c1ee31edb5a779534368e81ae0d0d7fe (patch) | |
tree | 34f9dc3068e33b3b341e3018978af042e81912e8 | |
parent | 2f229c53d7d16961b6ecfd2bb99e1c29e0a81715 (diff) | |
download | gpsd-de697118c1ee31edb5a779534368e81ae0d0d7fe.tar.gz |
First cut at read side of shared-memory exporter.
Untested, probably buggy. All regression tests pass.
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | gps.h | 4 | ||||
-rw-r--r-- | libgps_shm.c | 75 |
3 files changed, 78 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am index 2484c1e2..3d1cf3c2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -156,6 +156,7 @@ libgps_c_sources = \ json.c \ libgps_core.c \ libgps_json.c \ + libgps_shm.c \ netlib.c \ rtcm2_json.c \ shared_json.c \ @@ -1438,8 +1438,8 @@ extern const char /*@observer@*/ *gps_data(struct gps_data_t *); extern const char /*@observer@*/ *gps_errstr(const int); extern int gps_shm_open(/*@out@*/struct gps_data_t *); -extern int gps_shm_read(/*@out@*/struct gps_data_t *); -extern int gps_shm_close(struct gps_data_t *); +extern int gps_shm_read(struct gps_data_t *); +extern void gps_shm_close(struct gps_data_t *); /* this only needs to be visible for the unit tests */ extern int gps_unpack(char *, struct gps_data_t *); diff --git a/libgps_shm.c b/libgps_shm.c new file mode 100644 index 00000000..daf0f632 --- /dev/null +++ b/libgps_shm.c @@ -0,0 +1,75 @@ +/**************************************************************************** + +NAME + libgps_shm.c - reasder access to shared-memory export + +DESCRIPTION + This is a very lightweight alternative to JSON-over-sockets. Clients +won't be able to filter by device, and won't get device activation/deactivation +notifications. But both client and daemon will avoid all the marshalling and +unmarshalling overhead. + +PERMISSIONS + This file is Copyright (c) 2010 by the GPSD project + BSD terms apply: see the file COPYING in the distribution root for details. + +***************************************************************************/ +#include <stddef.h> +#include <string.h> +#include <errno.h> +#include <sys/time.h> +#include <sys/ipc.h> +#include <sys/shm.h> + +#include "gpsd.h" + +#ifdef SHM_EXPORT_ENABLE + +int gps_shm_open(/*@out@*/struct gps_data_t *gpsdata) +/* open a shared-memory connection to the daemon */ +{ + int shmid; + + gpsdata->privdata = NULL; + shmid = shmget((key_t)GPSD_KEY, sizeof(struct gps_data_t), 0); + if (shmid == -1) { + /* daemon isn't running or failed to create shared segment */ + return -1; + } + gpsdata->privdata = shmat(shmid, 0, 0); + if ((int)(long)gpsdata->privdata == -1) { + /* attach failed for sume unknown reason */ + return -2; + } + return 0; +} + +int gps_shm_read(struct gps_data_t *gpsdata) +/* read an update from the shared-memory segment */ +{ + if (gpsdata->privdata == NULL) + return -1; + else + { + int before, after; + struct shmexport_t *shared = (struct shmexport_t *)gpsdata->privdata; + + before = shared->bookend1; + (void)memcpy((void *)gpsdata, + (void *)&shared->gpsdata, + sizeof(struct gps_data_t)); + after = shared->bookend2; + /*@i1@*/gpsdata->privdata = shared; + return (before == after) ? 0 : -1; + } +} + +void gps_shm_close(struct gps_data_t *gpsdata) +{ + if (gpsdata->privdata != NULL) + (void)shmdt((const void *)gpsdata->privdata); +} + +#endif /* SHM_EXPORT_ENABLE */ + +/* end */ |