* Disentangled telemetry structure and shared memory handling.
LIB_NAME_OPTION=-soname
endif
+PLUGIN_SRC := telemetry.cpp shmget.c
+
.PHONY: all clean
all: telehttpd telelogger telemetry.so
-telemetry.so: telemetry.cpp $(SDK_HEADERS)
- g++ -o $@ -fPIC -Wall --shared -Wl,$(LIB_NAME_OPTION),$@ $(SDK_INCLUDES) telemetry.cpp
+telemetry.so: $(PLUGIN_SRC) $(SDK_HEADERS)
+ g++ -o $@ -fPIC -Wall --shared -Wl,$(LIB_NAME_OPTION),$@ $(SDK_INCLUDES) $(PLUGIN_SRC)
telehttpd: telehttpd.o shmget.o net.o fserv.o
$(CC) $(LDFLAGS) -o $@ -pthread $^
#include "shmget.h"
#include "log.h"
-struct telemetry_state_t *telemetry;
-int init_shm(void) {
+static void *init_shm_(int key, size_t size, int fl1, int fl2)
+{
int shmid;
+ void *shmhnd;
- shmid = shmget(SHM_KEY, sizeof *telemetry, 0);
+ shmid = shmget(key, size, fl1);
if ( 0 > shmid ) {
EPRINT( "shmget failed\n" );
- return -1;
+ return NULL;
+ }
+ shmhnd = shmat(shmid, NULL, fl2);
+ if ( (void *)-1 == shmhnd ) {
+ EPRINT( "shmat failed\n" );
+ return NULL;
}
- telemetry = shmat(shmid, NULL, SHM_RDONLY);
- if ((void *)-1 == telemetry) {
+ return shmhnd;
+}
+
+void *init_shmput(int key, size_t size)
+{
+ return init_shm_( key, size, IPC_CREAT | IPC_EXCL | 0600, 0 );
+}
+
+void *init_shmget(int key, size_t size) {
+ return init_shm_( key, size, 0, SHM_RDONLY );
+}
+
+int release_shm(int key, void *p)
+{
+ int shmid;
+
+ shmid = shmget(key, 0, 0);
+ if ( 0 > shmid ) {
EPRINT( "shmget failed\n" );
- shmdt(telemetry);
- return -2;
+ return -1;
}
+ shmdt( p );
+ shmctl( shmid, IPC_RMID, NULL );
return 0;
}
#ifndef SHMGET_H_
#define SHMGET_H_
-#include "telemetry.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
-extern struct telemetry_state_t *telemetry;
+extern void *init_shmput( int key, size_t size );
+extern void *init_shmget( int key, size_t size );
+extern int release_shm( int key, void *p );
-extern int init_shm(void);
+#ifdef __cplusplus
+}
+#endif
#endif /* SHMGET_H_ */
-
#include "net.h"
#include "log.h"
#include "shmget.h"
+#include "telemetry.h"
+static struct telemetry_state_t *telemetry;
struct {
int port;
if ( 0 != config( argc, argv ) )
exit( EXIT_FAILURE);
- if ( 0 != init_shm() )
+ if ( NULL == ( telemetry = init_shmget( TELE_SHM_KEY, sizeof *telemetry ) ) )
exit( EXIT_FAILURE);
if ( 0 != serve_http() )
#include <unistd.h>
#include "shmget.h"
+#include "telemetry.h"
+
+static struct telemetry_state_t *telemetry;
+
static const char *s2hms( int s ) {
static char buf[50];
}
int main(int argc, char *argv[]) {
- if ( 0 != init_shm() )
+ if ( NULL == ( telemetry = init_shmget( TELE_SHM_KEY, sizeof *telemetry ) ) )
exit( EXIT_FAILURE);
if ( 0 != log_console() )
exit( EXIT_FAILURE);
#include <unistd.h>
#include <signal.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
#define UNUSED(x)
-/**
- * @brief Last timestamp we received.
- */
-scs_timestamp_t last_timestamp = static_cast<scs_timestamp_t>(-1);
-
/**
* @brief Combined telemetry data and shared memory management.
*/
#include "telemetry.h"
-struct telemetry_state_t *telemetry;
+#include "shmget.h"
-static int shmid = -1;
+static struct telemetry_state_t *telemetry = NULL;
static bool init_shm(void)
{
- if ( 0 < shmid )
- return true;
- shmid = shmget(SHM_KEY, sizeof *telemetry, IPC_CREAT | IPC_EXCL | 0600);
- if ( 0 > shmid )
- return false;
- void *shmhnd;
- if ( (void *)-1 == (shmhnd = shmat(shmid, NULL, 0)) )
- return false;
- telemetry = static_cast<struct telemetry_state_t *>(shmhnd);
- memset(telemetry, 0, sizeof *telemetry);
- return true;
+ if ( NULL == telemetry ) {
+ void *p;
+ p = init_shmput( TELE_SHM_KEY, sizeof *telemetry );
+ telemetry = static_cast<struct telemetry_state_t *>(p);
+ }
+ assert( NULL != telemetry );
+ return NULL != telemetry;
}
-static void release_shm(void)
+static void drop_shm(void)
{
- if ( 0 < shmid) {
- shmdt(telemetry);
- shmctl(shmid, IPC_RMID, NULL);
- shmid = -1;
+ if ( NULL != telemetry ) {
+ release_shm( TELE_SHM_KEY, telemetry );
+ telemetry = NULL;
}
}
+/**
+ * @brief Last timestamp we received.
+ */
+scs_timestamp_t last_timestamp = static_cast<scs_timestamp_t>(-1);
+
+
/**
* @brief Function writting message to the game internal log.
*/
// Any cleanup needed. The registrations will be removed automatically
// so there is no need to do that manually.
- release_shm();
+ drop_shm();
}
// Cleanup
)
{
if (reason_for_call == DLL_PROCESS_DETACH) {
- release_shm();
+ drop_shm();
}
return TRUE;
}
#ifdef __linux__
void __attribute__ ((destructor)) unload(void)
{
- release_shm();
+ drop_shm();
}
#endif
#ifndef TELEMETRY_H_
#define TELEMETRY_H_
-#define SHM_KEY 0xecc11
+#define TELE_SHM_KEY 0xecc11
struct telemetry_state_t {
char game_id[10];