diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2018-12-25 09:53:52 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2018-12-25 09:53:52 +0100 |
commit | bab093ebbe392927a92ef201fe60344d5c1191dd (patch) | |
tree | 7f062abab2f17f614a3a81e2836a15e90cef3496 /compat | |
parent | 323dd162f5326b998e1c92ab4cfec8a63574023f (diff) |
compat/shm, proto/wine: remove duplication
The X-Plane plugin is next and should build on win32 then.
Diffstat (limited to 'compat')
-rw-r--r-- | compat/macros1.h | 9 | ||||
-rw-r--r-- | compat/shm.c | 150 | ||||
-rw-r--r-- | compat/shm.cpp | 134 | ||||
-rw-r--r-- | compat/shm.h | 85 | ||||
-rw-r--r-- | compat/shm.hpp | 34 |
5 files changed, 260 insertions, 152 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 |