123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- #include "gpsd_config.h"
- #ifdef SHM_EXPORT_ENABLE
- #include <errno.h>
- #include <stddef.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/ipc.h>
- #include <sys/shm.h>
- #include <sys/time.h>
- #include "gpsd.h"
- #include "libgps.h"
- bool shm_acquire(struct gps_context_t *context)
- {
- long shmkey = getenv("GPSD_SHM_KEY") ? strtol(getenv("GPSD_SHM_KEY"), NULL, 0) : GPSD_SHM_KEY;
- int shmid = shmget((key_t)shmkey, sizeof(struct shmexport_t), (int)(IPC_CREAT|0666));
- if (shmid == -1) {
- GPSD_LOG(LOG_ERROR, &context->errout,
- "shmget(0x%lx, %zd, 0666) for SHM export failed: %s\n",
- shmkey,
- sizeof(struct shmexport_t),
- strerror(errno));
- return false;
- } else
- GPSD_LOG(LOG_PROG, &context->errout,
- "shmget(0x%lx, %zd, 0666) for SHM export succeeded\n",
- shmkey,
- sizeof(struct shmexport_t));
- context->shmexport = (void *)shmat(shmid, 0, 0);
- if ((int)(long)context->shmexport == -1) {
- GPSD_LOG(LOG_ERROR, &context->errout,
- "shmat failed: %s\n", strerror(errno));
- context->shmexport = NULL;
- return false;
- }
- context->shmid = shmid;
- GPSD_LOG(LOG_PROG, &context->errout,
- "shmat() for SHM export succeeded, segment %d\n", shmid);
- return true;
- }
- void shm_release(struct gps_context_t *context)
- {
- if (context->shmexport == NULL)
- return;
-
- if (shmctl(context->shmid, IPC_RMID, NULL) == -1) {
- GPSD_LOG(LOG_WARN, &context->errout,
- "shmctl for IPC_RMID failed, errno = %d (%s)\n",
- errno, strerror(errno));
- }
- (void)shmdt((const void *)context->shmexport);
- }
- void shm_update(struct gps_context_t *context, struct gps_data_t *gpsdata)
- {
- if (context->shmexport != NULL)
- {
- static int tick;
- volatile struct shmexport_t *shared = (struct shmexport_t *)context->shmexport;
- ++tick;
-
- shared->bookend2 = tick;
- memory_barrier();
- shared->gpsdata = *gpsdata;
- memory_barrier();
- #ifndef USE_QT
- shared->gpsdata.gps_fd = SHM_PSEUDO_FD;
- #else
- shared->gpsdata.gps_fd = (void *)(intptr_t)SHM_PSEUDO_FD;
- #endif
- memory_barrier();
- shared->bookend1 = tick;
- }
- }
- #endif
|