#ifndef CRITICALSECTION_H
#define CRITICALSECTION_H

#if defined(_WIN32) || defined(_WIN64)

//#if defined(_DEBUG)
    #include <stdlib.h>
    #include <crtdbg.h>

    #include <windows.h>

//#endif

#else // assume POSIX

// kh 19.02.07 not really supported for linux, because the PSHARED parameter ist still(?) not supported

  #include <sys/types.h>
  #include <sys/ipc.h>
  #include <sys/shm.h>
  #include <sys/mman.h> 

  #include <unistd.h> 
  #include <stdio.h> 
  #include <stdlib.h> 
  #include <pthread.h> 
  #include <semaphore.h> 

  #include <string.h>

#endif

#if defined(_WIN32) || defined(_WIN64)

  extern "C"
  {
    #include "MPIWrapper.h"
  }

#else // assume POSIX

  extern "C"
  {
    #include "MPIWrapper.h"
  }
#endif

#define CRITICAL_SECTION_ENTER_TIMEOUT_INTERVAL 100 // kh 16.02.07 milliseconds

#define MAX_CRITICAL_SECTION_NAME              1024

/*
static long gnGlobalEnterTimeOutCount; 
static long gnGlobalEnteredCount;
*/

typedef struct 
{
#if defined(_WIN32) || defined(_WIN64)
	HANDLE  hMutexCriticalSection;
  char    sCriticalSectionName[MAX_CRITICAL_SECTION_NAME + 1];

	BOOL    bEntered;
#else
  
  sem_t   sem;
  char    sCriticalSectionName[MAX_CRITICAL_SECTION_NAME + 1];

	BOOL    bEntered;

#endif
} CriticalSection;

CriticalSection* CriticalSection_Construct(CriticalSection* pThis, char* sCriticalSectionName);

void CriticalSection_Destruct(CriticalSection* pThis);

void CriticalSection_Enter(CriticalSection* pThis);
void CriticalSection_Leave(CriticalSection* pThis);

#endif
