summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--compat/macros1.h9
-rw-r--r--compat/shm.c150
-rw-r--r--compat/shm.cpp134
-rw-r--r--compat/shm.h85
-rw-r--r--compat/shm.hpp34
-rw-r--r--proto-ft/ftnoir_protocol_ft.h8
-rw-r--r--proto-wine/ftnoir_protocol_wine.h4
-rw-r--r--proto-wine/opentrack-wrapper-wine-main.cxx114
-rw-r--r--proto-wine/opentrack-wrapper-wine-posix.cxx9
-rw-r--r--proto-wine/opentrack-wrapper-wine-windows.cxx6
10 files changed, 328 insertions, 225 deletions
diff --git a/compat/macros1.h b/compat/macros1.h
index fd2d4585..56f8e978 100644
--- a/compat/macros1.h
+++ b/compat/macros1.h
@@ -39,3 +39,12 @@
# define PP_EXPAND__2(x) PP_EXPAND__3(x) x
# define PP_EXPAND__3(x) x
#endif
+
+#ifdef _MSC_VER
+//# include <windows.h>
+//# define FULL_BARRIER MemoryBarrier()
+# define COMPILER_BARRIER() _ReadWriteBarrier()
+#else
+//# define FULL_BARRIER() __sync_synchronize()
+# define COMPILER_BARRIER() asm volatile("" ::: "memory")
+#endif
diff --git a/compat/shm.c b/compat/shm.c
new file mode 100644
index 00000000..d0c72781
--- /dev/null
+++ b/compat/shm.c
@@ -0,0 +1,150 @@
+#define BUILD_SHM
+#include "shm.h"
+
+#ifdef SHM_WIN32
+
+#include <windows.h>
+
+SHM_FUN(void, init, const char* shm_name, const char* mutex_name, int map_size)
+{
+ if (mutex_name != NULL)
+ {
+ self->mutex = CreateMutexA(NULL, false, mutex_name);
+
+ if (!self->mutex)
+ goto fail;
+ }
+
+ self->mapped_file = CreateFileMappingA(
+ INVALID_HANDLE_VALUE,
+ NULL,
+ PAGE_READWRITE,
+ 0,
+ (unsigned)map_size,
+ shm_name);
+
+ if (!self->mapped_file)
+ goto fail;
+
+ self->mem = MapViewOfFile(self->mapped_file,
+ FILE_MAP_WRITE,
+ 0,
+ 0,
+ (unsigned) map_size);
+
+ if (!self->mem)
+ goto fail;
+
+ return;
+
+fail:
+ SHM_FUN_NAME(free)(self);
+}
+
+SHM_FUN(void, free)
+{
+ if (self->mem)
+ (void) UnmapViewOfFile(self->mem);
+
+ if (self->mapped_file)
+ (void) CloseHandle(self->mapped_file);
+
+ if (self->mutex)
+ (void) CloseHandle(self->mutex);
+
+ self->mem = NULL;
+ self->mapped_file = NULL;
+ self->mutex = NULL;
+}
+
+SHM_FUN(void, lock)
+{
+ if (self->mutex)
+ (void)(WaitForSingleObject(self->mutex, INFINITE) == WAIT_OBJECT_0);
+}
+
+SHM_FUN(void, unlock)
+{
+ (void) ReleaseMutex(self->mutex);
+}
+
+SHM_FUN(bool, success)
+{
+ return self->mem != NULL;
+}
+
+#else
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/file.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <alloca.h>
+
+//#pragma GCC diagnostic ignored "-Wunused-result"
+
+SHM_FUN(void, init, const char *shm_name, const char* mutex_name, int map_size)
+{
+ char* filename = alloca(strlen(shm_name)+2);
+ (void)mutex_name;
+
+ self->mem = (void*)-1;
+ self->fd = -1;
+ self->size = 0;
+
+ if (map_size <= 0)
+ goto fail;
+
+ self->size = map_size;
+ strcpy(filename, "/");
+ strcat(filename, shm_name);
+ self->fd = shm_open(filename, O_RDWR | O_CREAT, 0600);
+ (void)ftruncate(self->fd, (off_t)map_size);
+ self->mem = mmap(NULL, (size_t)map_size, PROT_READ|PROT_WRITE, MAP_SHARED, self->fd, (off_t)0);
+
+ if (self->mem == (void*)-1)
+ goto fail;
+
+ return;
+
+fail:
+ SHM_FUN_NAME(free)(self);
+}
+
+SHM_FUN(void, free)
+{
+ if (self->mem != (void*)-1)
+ (void)munmap(self->mem, self->size);
+ if (self->fd != -1)
+ (void)close(self->fd);
+
+ self->mem = (void*)-1;
+ self->fd = -1;
+ self->size = 0;
+}
+
+SHM_FUN(void, lock)
+{
+ return flock(self->fd, LOCK_EX) == 0;
+}
+
+SHM_FUN(void, unlock)
+{
+ return flock(self->fd, LOCK_UN) == 0;
+}
+
+SHM_FUN(bool, success)
+{
+ return self->mem != (void*) -1;
+}
+
+#endif
+
+SHM_FUN(void*, ptr)
+{
+ return self->mem;
+}
diff --git a/compat/shm.cpp b/compat/shm.cpp
index 1f863190..ce01de2a 100644
--- a/compat/shm.cpp
+++ b/compat/shm.cpp
@@ -5,133 +5,23 @@
* copyright notice and this permission notice appear in all copies.
*/
-#include "shm.h"
+#define BUILD_SHM
+#include "shm.hpp"
-#if defined _WIN32
+SHMXX_TYPE_NAME& SHMXX_TYPE_NAME::operator=(SHMXX_TYPE_NAME&&) noexcept = default;
-#include <cstring>
-#include <cstdio>
-
-#include <accctrl.h>
-#include <aclapi.h>
-
-#ifdef QT_CORE_LIB
-# include <QDebug>
-# define warn(str, ...) (qDebug() << "shm:" str ": " << __VA_ARGS__)
-#else
-# define warn(str, ...) (void)0
-#endif
-
-shm_wrapper::shm_wrapper(const char* shm_name, const char* mutex_name, int map_size)
-{
- if (mutex_name == nullptr)
- mutex = nullptr;
- else
- {
- mutex = CreateMutexA(nullptr, false, mutex_name);
-
- if (!mutex)
- {
- warn("CreateMutexA", (int) GetLastError());
- return;
- }
- }
-
- mapped_file = CreateFileMappingA(
- INVALID_HANDLE_VALUE,
- nullptr,
- PAGE_READWRITE,
- 0,
- map_size,
- shm_name);
-
- if (!mapped_file)
- {
- warn("CreateFileMappingA", (int) GetLastError());
-
- return;
- }
-
- mem = MapViewOfFile(mapped_file,
- FILE_MAP_WRITE,
- 0,
- 0,
- map_size);
-
- if (!mem)
- warn("MapViewOfFile:", (int) GetLastError());
-}
-
-shm_wrapper::~shm_wrapper()
-{
- if (mem && !UnmapViewOfFile(mem))
- goto fail;
-
- if (mapped_file && !CloseHandle(mapped_file))
- goto fail;
-
- if (mutex && !CloseHandle(mutex))
- goto fail;
-
- return;
-
-fail:
- warn("failed to close mapping", (int) GetLastError());
-}
-
-bool shm_wrapper::lock()
-{
- if (mutex)
- return WaitForSingleObject(mutex, INFINITE) == WAIT_OBJECT_0;
- else
- return false;
-}
-
-bool shm_wrapper::unlock()
-{
- if (mutex)
- return ReleaseMutex(mutex);
- else
- return false;
-}
-#else
-
-#include <limits.h>
-
-#pragma GCC diagnostic ignored "-Wunused-result"
-shm_wrapper::shm_wrapper(const char *shm_name, const char* /*mutex_name*/, int map_size) : size(map_size)
-{
- char filename[PATH_MAX+2] {};
- strcpy(filename, "/");
- strcat(filename, shm_name);
- fd = shm_open(filename, O_RDWR | O_CREAT, 0600);
- (void) ftruncate(fd, map_size);
- mem = mmap(NULL, map_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, (off_t)0);
-}
-
-shm_wrapper::~shm_wrapper()
-{
- (void) munmap(mem, size);
- (void) close(fd);
-}
-
-bool shm_wrapper::lock()
-{
- return flock(fd, LOCK_EX) == 0;
-}
-
-bool shm_wrapper::unlock()
+// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
+SHMXX_TYPE_NAME::SHMXX_TYPE_NAME(const char* shm_name, const char* mutex_name, int map_size)
{
- return flock(fd, LOCK_UN) == 0;
+ shm_mem_impl_init(&impl, shm_name, mutex_name, map_size);
}
-#endif
-bool shm_wrapper::success()
+SHMXX_TYPE_NAME::~SHMXX_TYPE_NAME()
{
-#ifndef _WIN32
- return mem != (void*) -1;
-#else
- return mem != nullptr;
-#endif
+ shm_mem_impl_free(&impl);
}
+bool SHMXX_TYPE_NAME::success() noexcept { return shm_mem_impl_success(&impl); }
+void SHMXX_TYPE_NAME::lock() noexcept { shm_mem_impl_lock(&impl); }
+void SHMXX_TYPE_NAME::unlock() noexcept { shm_mem_impl_unlock(&impl); }
+void* SHMXX_TYPE_NAME::ptr() noexcept { return shm_mem_impl_ptr(&impl); }
diff --git a/compat/shm.h b/compat/shm.h
index 814ce90c..7cd7693d 100644
--- a/compat/shm.h
+++ b/compat/shm.h
@@ -1,41 +1,66 @@
-/* Copyright (c) 2013 Stanislaw Halik <sthalik@misaki.pl>
+#ifndef SHM_HEADER_GUARD
+#define SHM_HEADER_GUARD
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- */
-#pragma once
+#include "macros1.h"
-#if defined(_WIN32)
-#include <windows.h>
+#ifndef SHM_WIN32_INIT
+# ifdef _WIN32
+# define SHM_WIN32
+# else
+# undef SHM_WIN32
+# endif
#else
-#include <stdio.h>
-#include <string.h>
-#include <sys/file.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <unistd.h>
-#include <sys/types.h>
+# if SHM_WIN32_INIT
+# define SHM_WIN32
+# else
+# undef SHM_WIN32
+# endif
#endif
-#include "macros.hpp"
-#include "export.hpp"
+#ifndef SHM_TYPE_NAME
+# define SHM_TYPE_NAME shm_mem_impl
+#endif
+
+#ifndef SHM_FUN_PREFIX
+# define SHM_FUN_PREFIX shm_mem_impl_
+#endif
+
+#ifndef SHM_EXPORT
+# define SHM_EXPORT
+#endif
+
+#ifndef __cplusplus
+# define SHM_EXTERN
+# include <stdbool.h>
+struct SHM_TYPE_NAME;
+typedef struct SHM_TYPE_NAME SHM_TYPE_NAME;
+#else
+# define SHM_EXTERN extern "C"
+#endif
-class OTR_COMPAT_EXPORT shm_wrapper final
-{
+struct SHM_TYPE_NAME {
void* mem;
-#if defined(_WIN32)
- HANDLE mutex, mapped_file;
+#ifdef SHM_WIN32
+ void* mutex;
+ void* mapped_file;
#else
int fd, size;
#endif
-
-public:
- cc_noinline shm_wrapper(const char *shm_name, const char *mutex_name, int map_size);
- cc_noinline ~shm_wrapper();
- cc_noinline bool lock();
- cc_noinline bool unlock();
- cc_noinline bool success();
- inline void* ptr() { return mem; }
};
+
+#define SHM_FUN_NAME(f) PP_CAT(SHM_FUN_PREFIX, f)
+#define SHM_FUN(r, f, ...) SHM_EXTERN SHM_EXPORT r SHM_FUN_NAME(f)(SHM_TYPE_NAME* __restrict self, __VA_ARGS__)
+
+SHM_FUN(void, init, const char* shm_name, const char* mutex_name, int map_size);
+SHM_FUN(void, free);
+SHM_FUN(void, lock);
+SHM_FUN(void, unlock);
+SHM_FUN(void*,ptr);
+SHM_FUN(bool, success);
+
+#ifndef BUILD_SHM
+# undef SHM_FUN
+# undef SHM_FUN_NAME
+#endif
+
+#endif // SHM_HEADER_GUARD
diff --git a/compat/shm.hpp b/compat/shm.hpp
new file mode 100644
index 00000000..a8e0965b
--- /dev/null
+++ b/compat/shm.hpp
@@ -0,0 +1,34 @@
+/* Copyright (c) 2013 Stanislaw Halik <sthalik@misaki.pl>
+
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ */
+#ifndef SHMXX_HEADER_GUARD
+#define SHMXX_HEADER_GUARD
+
+#include "export.hpp"
+#include "shm.h"
+
+#ifndef SHMXX_TYPE_NAME
+# define SHMXX_TYPE_NAME mem
+#endif
+
+class OTR_COMPAT_EXPORT SHMXX_TYPE_NAME final
+{
+ shm_mem_impl impl;
+
+public:
+ SHMXX_TYPE_NAME(const char* shm_name, const char* mutex_name, int map_size);
+ ~SHMXX_TYPE_NAME();
+
+ bool success() noexcept;
+ void* ptr() noexcept;
+ void lock() noexcept;
+ void unlock() noexcept;
+
+ SHMXX_TYPE_NAME& operator=(const SHMXX_TYPE_NAME&) = delete;
+ SHMXX_TYPE_NAME& operator=(SHMXX_TYPE_NAME&&) noexcept;
+};
+
+#endif // SHMXX_HEADER_GUARD
diff --git a/proto-ft/ftnoir_protocol_ft.h b/proto-ft/ftnoir_protocol_ft.h
index 0056721c..a01ff722 100644
--- a/proto-ft/ftnoir_protocol_ft.h
+++ b/proto-ft/ftnoir_protocol_ft.h
@@ -19,7 +19,7 @@
#include <cinttypes>
#include "freetrackclient/fttypes.h"
-#include "compat/shm.h"
+#include "compat/shm.hpp"
#include "options/options.hpp"
#include <memory>
@@ -46,7 +46,7 @@ public:
QString game_name() override;
private:
settings s;
- shm_wrapper shm { FREETRACK_HEAP, FREETRACK_MUTEX, sizeof(FTHeap) };
+ mem shm { FREETRACK_HEAP, FREETRACK_MUTEX, sizeof(FTHeap) };
FTHeap* pMemData { (FTHeap*) shm.ptr() };
QProcess dummyTrackIR;
@@ -66,8 +66,8 @@ class FTControls: public IProtocolDialog
Q_OBJECT
public:
FTControls();
- void register_protocol(IProtocol *) {}
- void unregister_protocol() {}
+ void register_protocol(IProtocol *) override {}
+ void unregister_protocol() override {}
private:
Ui::UICFTControls ui;
settings s;
diff --git a/proto-wine/ftnoir_protocol_wine.h b/proto-wine/ftnoir_protocol_wine.h
index b4cbd305..8feaf0de 100644
--- a/proto-wine/ftnoir_protocol_wine.h
+++ b/proto-wine/ftnoir_protocol_wine.h
@@ -1,7 +1,7 @@
#pragma once
#include "api/plugin-api.hpp"
-#include "compat/shm.h"
+#include "compat/shm.hpp"
#include "wine-shm.h"
#include "ui_ftnoir_winecontrols.h"
@@ -33,7 +33,7 @@ public:
#endif
}
private:
- shm_wrapper lck_shm { WINE_SHM_NAME, WINE_MTX_NAME, sizeof(WineSHM) };
+ mem lck_shm { WINE_SHM_NAME, WINE_MTX_NAME, sizeof(WineSHM) };
WineSHM* shm = nullptr;
#ifndef OTR_WINE_NO_WRAPPER
diff --git a/proto-wine/opentrack-wrapper-wine-main.cxx b/proto-wine/opentrack-wrapper-wine-main.cxx
index 6370e7f4..491cc917 100644
--- a/proto-wine/opentrack-wrapper-wine-main.cxx
+++ b/proto-wine/opentrack-wrapper-wine-main.cxx
@@ -1,80 +1,74 @@
#include <cerrno>
+#include <unistd.h> // usleep
-// OSX sdk 10.8 build error otherwise
-#undef _LIBCPP_MSVCRT
-#include <cstdio>
-
+#include "compat/macros1.h"
#include "freetrackclient/fttypes.h"
#include "wine-shm.h"
-#include "compat/export.hpp"
enum Axis {
TX = 0, TY, TZ, Yaw, Pitch, Roll
};
-#include "compat/shm.h"
-
-void create_registry_key(void);
+#undef SHM_HEADER_GUARD
+#undef SHMXX_HEADER_GUARD
+#undef SHM_TYPE_NAME
+#undef SHM_FUN_PREFIX
+#undef SHMXX_TYPE_NAME
+#undef SHM_WIN32_INIT
+#define SHM_TYPE_NAME shm_impl_winelib
+#define SHM_FUN_PREFIX shm_impl_winelib_
+#define SHMXX_TYPE_NAME mem_winelib
+#define SHM_WIN32_INIT 1
+#include "compat/shm.hpp"
-class ShmPosix {
-public:
- ShmPosix(const char *shmName, const char *mutexName, int mapSize);
- ~ShmPosix();
- void lock();
- void unlock();
- bool success();
- inline void* ptr() { return mem; }
-private:
- void* mem;
- int fd, size;
-};
+#undef SHM_HEADER_GUARD
+#undef SHMXX_HEADER_GUARD
+#undef SHM_TYPE_NAME
+#undef SHM_FUN_PREFIX
+#undef SHMXX_TYPE_NAME
+#undef SHM_WIN32_INIT
+#define SHM_TYPE_NAME shm_impl_unix
+#define SHM_FUN_PREFIX shm_impl_unix_
+#define SHMXX_TYPE_NAME mem_unix
+#define SHM_WIN32_INIT
+#include "compat/shm.hpp"
-class ShmWine {
-public:
- ShmWine(const char *shmName, const char *mutexName, int mapSize);
- ~ShmWine();
- void lock();
- void unlock();
- bool success();
- inline void* ptr() { return mem; }
-private:
- void* mem;
- void *hMutex, *hMapFile;
-};
-#include <windows.h>
+void create_registry_key(void);
int main(void)
{
- ShmPosix lck_posix(WINE_SHM_NAME, WINE_MTX_NAME, sizeof(WineSHM));
- ShmWine lck_wine("FT_SharedMem", "FT_Mutext", sizeof(FTHeap));
- if(!lck_posix.success()) {
- fprintf(stderr, "Can't open posix map: %d\n", errno);
+ mem_unix lck_unix(WINE_SHM_NAME, WINE_MTX_NAME, sizeof(WineSHM));
+ mem_winelib lck_wine("FT_SharedMem", "FT_Mutext", sizeof(FTHeap));
+
+ if(!lck_unix.success())
return 1;
- }
- if(!lck_wine.success()) {
- fprintf(stderr, "Can't open Wine map\n");
+ if(!lck_wine.success())
return 1;
- }
- WineSHM* shm_posix = (WineSHM*) lck_posix.ptr();
- FTHeap* shm_wine = (FTHeap*) lck_wine.ptr();
- FTData* data = &shm_wine->data;
+
create_registry_key();
- while (1) {
- if (shm_posix->stop)
- break;
- data->Yaw = -shm_posix->data[Yaw];
- data->Pitch = -shm_posix->data[Pitch];
- data->Roll = shm_posix->data[Roll];
- data->X = shm_posix->data[TX];
- data->Y = shm_posix->data[TY];
- data->Z = shm_posix->data[TZ];
- data->DataID++;
- data->CamWidth = 250;
- data->CamHeight = 100;
- shm_wine->GameID2 = shm_posix->gameid2;
- shm_posix->gameid = shm_wine->GameID;
+
+ WineSHM& mem_unix = *(WineSHM*) lck_unix.ptr();
+ FTHeap& mem_wine = *(FTHeap*) lck_wine.ptr();
+ FTData& data = mem_wine.data;
+
+ data.CamWidth = 250;
+ data.CamHeight = 100;
+
+ while (!mem_unix.stop)
+ {
+ MEMBAR();
+ data.Yaw = -mem_unix.data[Yaw];
+ data.Pitch = -mem_unix.data[Pitch];
+ data.Roll = mem_unix.data[Roll];
+ data.X = mem_unix.data[TX];
+ data.Y = mem_unix.data[TY];
+ data.Z = mem_unix.data[TZ];
+ data.DataID = 1;
+ mem_wine.GameID2 = mem_unix.gameid2;
+ mem_unix.gameid = mem_wine.GameID;
for (int i = 0; i < 8; i++)
- shm_wine->table[i] = shm_posix->table[i];
- (void) Sleep(4);
+ mem_wine.table[i] = mem_wine.table[i];
+ MEMBAR();
+ (void)usleep(4 * 1000);
}
}
diff --git a/proto-wine/opentrack-wrapper-wine-posix.cxx b/proto-wine/opentrack-wrapper-wine-posix.cxx
index e36407a9..17a74b66 100644
--- a/proto-wine/opentrack-wrapper-wine-posix.cxx
+++ b/proto-wine/opentrack-wrapper-wine-posix.cxx
@@ -1,7 +1,6 @@
-#ifdef _WIN32
-# undef _WIN32
-#endif
+#undef _WIN32
-#define shm_wrapper ShmPosix
-#include "compat/shm.h"
+#define SHM_TYPE_NAME shm_impl_unix
+#define SHM_FUN_PREFIX shm_impl_unix_
+#define SHMXX_TYPE_NAME mem_unix
#include "compat/shm.cpp"
diff --git a/proto-wine/opentrack-wrapper-wine-windows.cxx b/proto-wine/opentrack-wrapper-wine-windows.cxx
index d464cf6c..a18900c3 100644
--- a/proto-wine/opentrack-wrapper-wine-windows.cxx
+++ b/proto-wine/opentrack-wrapper-wine-windows.cxx
@@ -2,9 +2,11 @@
# error "bad cross"
#endif
-#define shm_wrapper ShmWine
-#include "compat/shm.h"
+#define SHM_TYPE_NAME shm_impl_winelib
+#define SHM_FUN_PREFIX shm_impl_winelib_
+#define SHMXX_TYPE_NAME mem_winelib
#include "compat/shm.cpp"
+
#include "wine-shm.h"
#include "compat/library-path.hpp"
#include <cstring>