Fixes to Windows shared memory handling for VoD.

This commit is contained in:
Thulinma 2015-04-16 15:59:25 +02:00
parent f20f1607c6
commit e672959f96
3 changed files with 40 additions and 17 deletions

View file

@ -14,6 +14,17 @@
#include "procs.h" #include "procs.h"
namespace IPC { namespace IPC {
#if defined(__CYGWIN__) || defined(_WIN32)
static std::map<std::string, sharedPage> preservedPages;
void preservePage(std::string p){
preservedPages[p].init(p, 0, false, false);
}
void releasePage(std::string p){
preservedPages.erase(p);
}
#endif
/// Stores a long value of val in network order to the pointer p. /// Stores a long value of val in network order to the pointer p.
static void htobl(char * p, long val) { static void htobl(char * p, long val) {
p[0] = (val >> 24) & 0xFF; p[0] = (val >> 24) & 0xFF;
@ -63,7 +74,7 @@ namespace IPC {
///\brief Empty semaphore constructor, clears all values ///\brief Empty semaphore constructor, clears all values
semaphore::semaphore() { semaphore::semaphore() {
#ifdef __CYGWIN__ #if defined(__CYGWIN__) || defined(_WIN32)
mySem = 0; mySem = 0;
#else #else
mySem = SEM_FAILED; mySem = SEM_FAILED;
@ -76,7 +87,7 @@ namespace IPC {
///\param mode The mode in which to create the semaphore, if O_CREAT is given in oflag, ignored otherwise ///\param mode The mode in which to create the semaphore, if O_CREAT is given in oflag, ignored otherwise
///\param value The initial value of the semaphore if O_CREAT is given in oflag, ignored otherwise ///\param value The initial value of the semaphore if O_CREAT is given in oflag, ignored otherwise
semaphore::semaphore(const char * name, int oflag, mode_t mode, unsigned int value) { semaphore::semaphore(const char * name, int oflag, mode_t mode, unsigned int value) {
#ifdef __CYGWIN__ #if defined(__CYGWIN__) || defined(_WIN32)
mySem = 0; mySem = 0;
#else #else
mySem = SEM_FAILED; mySem = SEM_FAILED;
@ -92,7 +103,7 @@ namespace IPC {
///\brief Returns whether we have a valid semaphore ///\brief Returns whether we have a valid semaphore
semaphore::operator bool() const { semaphore::operator bool() const {
#ifdef __CYGWIN__ #if defined(__CYGWIN__) || defined(_WIN32)
return mySem != 0; return mySem != 0;
#else #else
return mySem != SEM_FAILED; return mySem != SEM_FAILED;
@ -110,7 +121,7 @@ namespace IPC {
close(); close();
int timer = 0; int timer = 0;
while (!(*this) && timer++ < 10){ while (!(*this) && timer++ < 10){
#ifdef __CYGWIN__ #if defined(__CYGWIN__) || defined(_WIN32)
mySem = CreateSemaphore(0, value, 1 , std::string("Global\\" + std::string(name)).c_str()); mySem = CreateSemaphore(0, value, 1 , std::string("Global\\" + std::string(name)).c_str());
#else #else
if (oflag & O_CREAT) { if (oflag & O_CREAT) {
@ -135,7 +146,7 @@ namespace IPC {
///\brief Returns the current value of the semaphore ///\brief Returns the current value of the semaphore
int semaphore::getVal() const { int semaphore::getVal() const {
#ifdef __CYGWIN__ #if defined(__CYGWIN__) || defined(_WIN32)
LONG res; LONG res;
ReleaseSemaphore(mySem, 0, &res);//not really release.... just checking to see if I can get the value this way ReleaseSemaphore(mySem, 0, &res);//not really release.... just checking to see if I can get the value this way
#else #else
@ -148,7 +159,7 @@ namespace IPC {
///\brief Posts to the semaphore, increases its value by one ///\brief Posts to the semaphore, increases its value by one
void semaphore::post() { void semaphore::post() {
if (*this) { if (*this) {
#ifdef __CYGWIN__ #if defined(__CYGWIN__) || defined(_WIN32)
ReleaseSemaphore(mySem, 1, 0); ReleaseSemaphore(mySem, 1, 0);
#else #else
sem_post(mySem); sem_post(mySem);
@ -159,7 +170,7 @@ namespace IPC {
///\brief Waits for the semaphore, decreases its value by one ///\brief Waits for the semaphore, decreases its value by one
void semaphore::wait() { void semaphore::wait() {
if (*this) { if (*this) {
#ifdef __CYGWIN__ #if defined(__CYGWIN__) || defined(_WIN32)
WaitForSingleObject(mySem, INFINITE); WaitForSingleObject(mySem, INFINITE);
#else #else
int tmp; int tmp;
@ -173,7 +184,7 @@ namespace IPC {
///\brief Tries to wait for the semaphore, returns true if successfull, false otherwise ///\brief Tries to wait for the semaphore, returns true if successfull, false otherwise
bool semaphore::tryWait() { bool semaphore::tryWait() {
bool result; bool result;
#ifdef __CYGWIN__ #if defined(__CYGWIN__) || defined(_WIN32)
result = WaitForSingleObject(mySem, 0);//wait at most 1ms result = WaitForSingleObject(mySem, 0);//wait at most 1ms
#else #else
result = sem_trywait(mySem); result = sem_trywait(mySem);
@ -184,7 +195,7 @@ namespace IPC {
///\brief Closes the currently opened semaphore ///\brief Closes the currently opened semaphore
void semaphore::close() { void semaphore::close() {
if (*this) { if (*this) {
#ifdef __CYGWIN__ #if defined(__CYGWIN__) || defined(_WIN32)
CloseHandle(mySem); CloseHandle(mySem);
mySem = 0; mySem = 0;
#else #else
@ -197,7 +208,7 @@ namespace IPC {
///\brief Unlinks the previously opened semaphore ///\brief Unlinks the previously opened semaphore
void semaphore::unlink() { void semaphore::unlink() {
close(); close();
#ifndef __CYGWIN__ #if defined(__CYGWIN__) || defined(_WIN32)
if (myName.size()) { if (myName.size()) {
sem_unlink(myName.c_str()); sem_unlink(myName.c_str());
} }
@ -238,7 +249,7 @@ namespace IPC {
///\brief Unmaps a shared page if allowed ///\brief Unmaps a shared page if allowed
void sharedPage::unmap() { void sharedPage::unmap() {
if (mapped && len) { if (mapped && len) {
#ifdef __CYGWIN__ #if defined(__CYGWIN__) || defined(_WIN32)
//under Cygwin, the mapped location is shifted by 4 to contain the page size. //under Cygwin, the mapped location is shifted by 4 to contain the page size.
UnmapViewOfFile(mapped-4); UnmapViewOfFile(mapped-4);
#else #else
@ -253,7 +264,8 @@ namespace IPC {
void sharedPage::close() { void sharedPage::close() {
unmap(); unmap();
if (handle > 0) { if (handle > 0) {
#ifdef __CYGWIN__ INSANE_MSG("Closing page %s in %s mode", name.c_str(), master?"master":"client");
#if defined(__CYGWIN__) || defined(_WIN32)
CloseHandle(handle); CloseHandle(handle);
#else #else
::close(handle); ::close(handle);
@ -291,7 +303,7 @@ namespace IPC {
mapped = 0; mapped = 0;
if (name.size()) { if (name.size()) {
INSANE_MSG("Opening page %s in %s mode %s auto-backoff", name.c_str(), master?"master":"client", autoBackoff?"with":"without"); INSANE_MSG("Opening page %s in %s mode %s auto-backoff", name.c_str(), master?"master":"client", autoBackoff?"with":"without");
#ifdef __CYGWIN__ #if defined(__CYGWIN__) || defined(_WIN32)
if (master) { if (master) {
//Under cygwin, all pages are 4 bytes longer than claimed. //Under cygwin, all pages are 4 bytes longer than claimed.
handle = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, len+4, name.c_str()); handle = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, len+4, name.c_str());
@ -422,7 +434,6 @@ namespace IPC {
void sharedFile::close() { void sharedFile::close() {
unmap(); unmap();
if (handle > 0) { if (handle > 0) {
INSANE_MSG("Closing page %s in %s mode", name.c_str(), master?"master":"client");
::close(handle); ::close(handle);
if (master && name != "") { if (master && name != "") {
unlink(name.c_str()); unlink(name.c_str());

View file

@ -5,7 +5,7 @@
#include "timing.h" #include "timing.h"
#include "defines.h" #include "defines.h"
#ifdef __CYGWIN__ #if defined(__CYGWIN__) || defined(_WIN32)
#include <windows.h> #include <windows.h>
#else #else
#include <semaphore.h> #include <semaphore.h>
@ -67,7 +67,7 @@ namespace IPC {
void close(); void close();
void unlink(); void unlink();
private: private:
#ifdef __CYGWIN__ #if defined(__CYGWIN__) || defined(_WIN32)
HANDLE mySem; HANDLE mySem;
#else #else
sem_t * mySem; sem_t * mySem;
@ -112,6 +112,12 @@ namespace IPC {
}; };
#ifdef SHM_ENABLED #ifdef SHM_ENABLED
#if defined(__CYGWIN__) || defined(_WIN32)
void preservePage(std::string);
void releasePage(std::string);
#endif
///\brief A class for managing shared memory pages. ///\brief A class for managing shared memory pages.
class sharedPage { class sharedPage {
public: public:
@ -126,7 +132,7 @@ namespace IPC {
} }
void unmap(); void unmap();
void close(); void close();
#ifdef __CYGWIN__ #if defined(__CYGWIN__) || defined(_WIN32)
///\brief The handle of the opened shared memory page ///\brief The handle of the opened shared memory page
HANDLE handle; HANDLE handle;
#else #else

View file

@ -143,6 +143,9 @@ namespace Mist {
toErase.init(pageName, pagesByTrack[tid][pageNumber].dataSize, false); toErase.init(pageName, pagesByTrack[tid][pageNumber].dataSize, false);
#endif #endif
//Set the master flag so that the page will be destoryed once it leaves scope //Set the master flag so that the page will be destoryed once it leaves scope
#if defined(__CYGWIN__) || defined(_WIN32)
IPC::releasePage(pageName);
#endif
toErase.master = true; toErase.master = true;
//Remove the page from the tracks index page //Remove the page from the tracks index page
@ -275,6 +278,9 @@ namespace Mist {
INFO_MSG("Succesfully registered page %lu on the metaPage of track %lu~>%lu.", curPageNum[tid], tid, mapTid); INFO_MSG("Succesfully registered page %lu on the metaPage of track %lu~>%lu.", curPageNum[tid], tid, mapTid);
} }
//Close our link to the page. This will NOT destroy the shared page, as we've set master to false upon construction //Close our link to the page. This will NOT destroy the shared page, as we've set master to false upon construction
#if defined(__CYGWIN__) || defined(_WIN32)
IPC::preservePage(curPage[tid].name);
#endif
curPage.erase(tid); curPage.erase(tid);
curPageNum.erase(tid); curPageNum.erase(tid);
} }