//////////////////////////////////////////////////////////////////////////////////
//
// File:        NSPR_Locks.cpp
//
// Description: This file has functions to emulate the NSPR lock functions.
//              
//
// Author:      Ian Honcharuk - 5/04/06
//
//////////////////////////////////////////////////////////////////////////////////
#include "java.h"

#include "NSPR_Locks.h"


////////////////////////////////////////////////////////////////////////////////
// 
// Method:      CNLock* CN_NewLock()
//
// Parameters:  (OUT) char * - the user's name;          
//
// Returns:     CNLock* - A new lock if succesful otherwise NULL
//
// Scope:       public
//
// Description: Creates a new lock            
//
// Assumptions: 
//
// Author:      Ian Honcharuk - 5/04/06
//
////////////////////////////////////////////////////////////////////////////////

#ifdef TPS

NU_SEMAPHORE CN_lock_semaphore;
CNLock* CN_NewLock()
{
	NU_Create_Semaphore(&CN_lock_semaphore,"CN_LOCK",1,NU_FIFO);
	return &CN_lock_semaphore;
}

#else

CNLock* CN_NewLock()
{
	CNLock* new_lock = (CNLock*) calloc(1,sizeof (CNLock));

	// In low memory situations, InitializeCriticalSection can raise a STATUS_NO_MEMORY exception.
	InitializeCriticalSection(new_lock);
	
	return new_lock;
}

#endif
////////////////////////////////////////////////////////////////////////////////
// 
// Method:      CNLock* CN_DestroyLock()
//
// Parameters:  (IN) CNLock * - a pointer to a lock;          
//
// Returns:     
//
// Scope:       public
//
// Description: Destroys a lock          
//
// Assumptions: 
//
// Author:      Ian Honcharuk - 5/04/06
//
////////////////////////////////////////////////////////////////////////////////
void CN_DestroyLock(CNLock* lock)
{
#ifdef TPS
	NU_Delete_Semaphore(&CN_lock_semaphore);
#else
	DeleteCriticalSection(lock);
#endif
}

////////////////////////////////////////////////////////////////////////////////
// 
// Method:      CNLock* CN_Lock()
//
// Parameters:  (IN) CNLock * - a pointer to a lock;          
//
// Returns:     
//
// Scope:       public
//
// Description: Lock the specified lock object. Blocks any other call to CN_Lock until
//				the lock is released.          
//
// Assumptions: 
//
// Author:      Ian Honcharuk - 5/04/06
//
////////////////////////////////////////////////////////////////////////////////
void CN_Lock(CNLock* lock)
{
#ifdef TPS
    /*if(g_OwnerThread)
	{
		if(g_OwnerThread == TCD_Current_Thread)
		{
			g_OwnerThreadCntr++;
			return;
		}
	}
	NU_Obtain_Semaphore(&CN_lock_semaphore,NU_SUSPEND);
	g_OwnerThread = TCD_Current_Thread;
	g_OwnerThreadCntr = 1;*/
#else
	EnterCriticalSection(lock);
#endif
}

////////////////////////////////////////////////////////////////////////////////
// 
// Method:      CNLock* CN_Lock()
//
// Parameters:  (IN) CNLock * - a pointer to a lock;          
//
// Returns:     
//
// Scope:       public
//
// Description: Lock the specified lock object. Blocks any other call to CN_Lock until
//				the lock is released.          
//
// Assumptions: 
//
// Author:      Ian Honcharuk - 5/04/06
//
////////////////////////////////////////////////////////////////////////////////
CNStatus CN_Unlock(CNLock* lock)
{
#ifdef TPS
	/*g_OwnerThreadCntr--;
	if(g_OwnerThreadCntr <= 0)
	{
        g_OwnerThread = NULL;
		NU_Release_Semaphore(&CN_lock_semaphore);
	}*/
#else
	LeaveCriticalSection(lock);
#endif
	return PR_SUCCESS;
}