/********************************************************************************
* FaceTrackNoIR This program is a private project of the some enthusiastic *
* gamers from Holland, who don't like to pay much for *
* head-tracking. *
* *
* Copyright (c) 2013 Stanisław 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. *
* *
* *
* Compat Compat is the Class, that makes memory-mapping convenient *
********************************************************************************/
/*
Modifications (last one on top):
20130504 - WVR: Added some checking and decoration.
20130404 - STH: Initial version.
*/
#define IN_FTNOIR_COMPAT
#include "compat.h"
#if defined(_WIN32) || defined(__WIN32)
//
// Contructor for the Portable Locked Shared Memory.
//
PortableLockedShm::PortableLockedShm(const char* shmName, const char* mutexName, int mapSize)
{
bool bFirst = true;
//
// Create the mutex for locking the memory.
//
hMutex = CreateMutexA(NULL, false, mutexName);
//
// Create the file-mapping (check if it was already there).
//
hMapFile = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, mapSize, shmName);
if ( ( hMapFile != 0 ) && ( (long) GetLastError == ERROR_ALREADY_EXISTS ) ) {
bFirst = false;
}
//
// Map the View into process address space
//
mem = MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, mapSize);
if ((mem != NULL) && (bFirst)) {
memset(mem, 0, mapSize); // Write zero's, if first...
}
}
//
// Destructor for the Portable Locked Shared Memory.
//
PortableLockedShm::~PortableLockedShm()
{
if (mem != NULL)
UnmapViewOfFile(mem);
if (hMapFile != NULL)
CloseHandle(hMapFile);
if (hMutex != NULL)
CloseHandle(hMutex);
}
//
// Lock the Portable Locked Shared Memory.
//
void PortableLockedShm::lock()
{
(void) WaitForSingleObject(hMutex, INFINITE);
}
//
// UnLock the Portable Locked Shared Memory.
//
void PortableLockedShm::unlock()
{
(void) ReleaseMutex(hMutex);
}
#else
PortableLockedShm::PortableLockedShm(const char *shmName, const char *mutexName, int mapSize) : size(mapSize)
{
char shm_filename[NAME_MAX];
shm_filename[0] = '/';
strncpy(shm_filename+1, shmName, NAME_MAX-2);
sprintf(shm_filename + strlen(shm_filename), "%ld\n", (long) getuid());
shm_filename[NAME_MAX-1] = '\0';
//(void) shm_unlink(shm_filename);
fd = shm_open(shm_filename, O_RDWR | O_CREAT, 0600);
if (ftruncate(fd, mapSize) == 0)
mem = mmap(NULL, mapSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, (off_t)0);
else
mem = (void*) -1;
}
PortableLockedShm::~PortableLockedShm()
{
//(void) shm_unlink(shm_filename);
(void) munmap(mem, size);
(void) close(fd);
}
void PortableLockedShm::lock()
{
flock(fd, LOCK_EX);
}
void PortableLockedShm::unlock()
{
flock(fd, LOCK_UN);
}
#endif