#ifndef OS_SYNC_H
#define OS_SYNC_H

#ifdef _WIN32_
typedef enum		/* SEM_B_STATE */
{
	SEM_EMPTY,			/* 0: semaphore not available */
	SEM_FULL			/* 1: semaphore available */
} SEM_B_STATE;	
	#pragma once
	#include <afxmt.h>		
	#define SYNC_HANDLE HANDLE
	#define WAIT_FOREVER INFINITE
	#define THREAD_MUTEX_HANDLE CRITICAL_SECTION 
#endif
#ifdef _VXWORKS_
	// For mutex implementation using mutual-exclusion semaphores (which
	// can be taken recursively).
	#include <vxwMutex.h>
	/* semaphore options */
	#define SEM_Q_MASK		0x3 /* q-type mask */
	#define SEM_Q_FIFO		0x0 /* first in first out queue */
	#define SEM_Q_PRIORITY		0x1 /* priority sorted queue */
	#define SEM_DELETE_SAFE		0x4 /* owner delete safe (mutex opt.) */
	#define SEM_INVERSION_SAFE	0x8 /* no priority inversion (mutex opt.) */
	#define INFINITE		(-1)	   
	#define SYNC_HANDLE 		SEM_ID
	#define SEM_NULL 		(SYNC_HANDLE )0
	#define THREAD_MUTEX_HANDLE 	vxw_mutex_t
	#define LPSECURITY_ATTRIBUTES 	int *
#endif	

class DefaultSecurity
{
public:
	DefaultSecurity(){};
	static LPSECURITY_ATTRIBUTES attributes();
};

class Sync
{
public:	
	Sync(){};

	virtual ~Sync(){};

	virtual int lock() = 0;

	virtual int unlock() = 0;	

};

class ThreadMutex : public Sync
{
public:	
	ThreadMutex();

	~ThreadMutex();

	int lock();

	int unlock();

	void init();
	
	THREAD_MUTEX_HANDLE *handle();

private:
	THREAD_MUTEX_HANDLE _synchandle;	
};

class BinarySemaphore
{
public:
	BinarySemaphore(SEM_B_STATE initcount = SEM_EMPTY, const char *name = NULL);

	~BinarySemaphore();

	// Wait for semaphore <milliSeconds>
	// Returns -1 if wait timed out
	int semTake(int milliSeconds = WAIT_FOREVER);

	// Gives semaphore. Releases all threads waiting for this
	// Binary semaphore
	int semGive();

	SYNC_HANDLE *handle();

private:

	SYNC_HANDLE _synchandle;		
};

template <class LOCK>
class Guard
{
  // = TITLE
  //     This data structure is meant to be used within a method or
  //     function...  It performs automatic aquisition and release of
  //     a parameterized synchronization object <LOCK>.
  //
  // = DESCRIPTION
  //     The <LOCK> class given as an actual parameter must provide at
  //     the very least the <acquire>, <release>, and <remove> methods.
public:

 // = Initialization and termination methods.

  Guard (LOCK &l): _lock (&l)
  {
    acquire ();
  }
  // Implicitly and automatically acquire (or try to acquire) the
  // lock.  
  ~Guard (void)
  {
    release ();
  }
  // Implicitly release the lock.

  // = Lock accessors.

  int acquire (void) { return  _owner = _lock->lock (); }
  // Explicitly acquire the lock.

  int release (void) { if (_owner == -1) return 0; return _lock->unlock ();  }
  // Explicitly release the lock, but only if it is held!

  int remove (void) { return _lock->unlock (); }
  // Explicitly remove the lock.

   // = Utility methods.
  int locked (void) { return _owner != -1; }
  // 1 if locked, 0 if couldn't acquire the lock
  // (errno will contain the reason for this).

protected:

  LOCK *_lock;
  // Pointer to the LOCK we're guarding.

  int _owner;
  // Keeps track of whether we acquired the lock or failed.

};

#endif // ! defined OS_SYNC_H
