/* Copyright (c) 2013 Stanislaw Halik * 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. */ #include "shm.h" #if defined _WIN32 #include #include #include #include #if !defined __WINE__ # include # 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 #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() { return flock(fd, LOCK_UN) == 0; } #endif bool shm_wrapper::success() { #ifndef _WIN32 return mem != (void*) -1; #else return mem != NULL; #endif }