/*
 * voipSem.cpp
 *
 * Copyright (C) 2005, Ranch Networks, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 *
 * Author : Srivatsa Chivukula <srivatsa@ranchnetworks.com>
 *
 */

#include "sysError.h"

#include "voipSem.h"

#ifdef POSIX
#include <stdio.h>
#endif

/*****  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  *****/


// BEGIN: Mutex Semaphore related definitions

voipMutexSemaphore::voipMutexSemaphore ( void )
{
   // No specifcs for base class
   semId = SEMAPHORE_IS_INVALID;
   q = QUEUE_IS_INVALID;
}

voipMutexSemaphore::~voipMutexSemaphore ( void )
{
   if(  semId != SEMAPHORE_IS_INVALID  )
   {
#if defined VXWORKS
	  semGive( semId  );
      semDelete( semId  );
#elif defined WIN32
      ReleaseMutex( semId );
      CloseHandle( semId );
#elif defined POSIX
	  pthread_mutex_unlock( semId );
	  pthread_mutex_destroy( semId );
	  semId = SEMAPHORE_IS_INVALID;
#endif
   }
}

int voipMutexSemaphore::grab ( unsigned long wait_time=WAIT_FOREVER )
{
   if ( semId == SEMAPHORE_IS_INVALID )
      return ( SYS_FAILURE );

#if defined VXWORKS
   if ( semTake( semId, (int)wait_time  ) == OK )
#elif defined WIN32
   if ( WaitForSingleObject( semId, wait_time ) == WAIT_OBJECT_0 )
#elif defined POSIX
   if ( pthread_mutex_lock( semId ) == OK )
#endif
	   return (SYS_SUCCESS);
   return ( -SYS_FAILURE );
}

int voipMutexSemaphore::release ( void )
{
   if ( semId == SEMAPHORE_IS_INVALID )
      return ( -SYS_FAILURE );

#if defined VXWORKS
   if ( semGive( semId ) == OK )
#elif defined WIN32
   if ( ReleaseMutex( semId ) )
#elif defined POSIX
   if ( pthread_mutex_unlock( semId ) == OK )
#endif
      return ( SYS_SUCCESS );
   else
      return ( -SYS_FAILURE );
}

int voipMutexSemaphore::destroy ( void )
{
   if ( semId == SEMAPHORE_IS_INVALID )
      return ( SYS_SUCCESS );

#if defined VXWORKS   
   if ( semDelete( semId  ) == OK )
#elif defined WIN32
   if ( CloseHandle( semId ) == OK )
#elif defined POSIX
   if ( pthread_mutex_destroy( semId ) == OK )
#endif
   {
      semId = SEMAPHORE_IS_INVALID;
      return ( SYS_SUCCESS );
   }
   else
   {
      semId = SEMAPHORE_IS_INVALID;
      return ( -SYS_FAILURE );
   }
}

#if defined VXWORKS
int voipMutexSemaphore::flush ( void )
{
   if ( semId == SEMAPHORE_IS_INVALID )
      return ( SYS_SUCCESS );

   if ( semFlush( semId  ) == OK )
      return ( SYS_SUCCESS );
   else
      return ( -SYS_FAILURE );
}
#endif

int voipMutexSemaphore::qType ( void )
{
   return ( q );
}

inline int voipMutexSemaphore::setSemId ( SEM_ID id )
{
   semId = id;
   return ( SYS_SUCCESS );
}

inline int voipMutexSemaphore::setQType ( int qType )
{
   q = qType;
   return ( SYS_SUCCESS );
}

SEM_ID voipMutexSemaphore::handle ( void )
{
   return (semId );
}

int voipMutexSemaphore::create ( int qtype  )
{
   SEM_ID semMutex;

#if defined VXWORKS
   semMutex = semMCreate(qtype | SEM_DELETE_SAFE );
   if(  semMutex != 0  )
   {
      setSemId ( semMutex );
      setQType ( qtype );
      return ( SYS_SUCCESS );
   }
   return -SYS_FAILURE;
#elif defined WIN32
   semMutex = CreateMutex(NULL, FALSE, NULL);
   if(  semMutex != NULL  )
   {
      setSemId ( semMutex );
      setQType ( qtype );
      return ( SYS_SUCCESS );
   }
   return -SYS_FAILURE;
#elif defined POSIX
   int status;

   semMutex = (SEM_ID)malloc(sizeof(pthread_mutex_t));
   if ( semMutex == NULL )
	   return -SYS_FAILURE;
   status = pthread_mutex_init(semMutex, NULL);
   if ( status == 0 )
   {
      setSemId ( semMutex );
      setQType ( qtype );
      return ( SYS_SUCCESS );
   }
   return -SYS_FAILURE;
#endif
        

}

int voipMutexSemaphore::state (  )
{
   // No specifcs for now
   return ( SEM_FULL );
}


// END: Mutex Semaphore related definitions

/*****  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  *****/

