/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT    Copyright (C) 1995 IBM Corporation                           */
/*                                                                           */
/*    The following IBM OS/2 WARP source code is provided to you solely for  */
/*    the purpose of assisting you in your development of OS/2 WARP device   */
/*    drivers. You may use this code in accordance with the IBM License      */
/*    Agreement provided in the IBM Device Driver Source Kit for OS/2. This  */
/*    Copyright statement may not be removed.                                */
/*                                                                           */
/*****************************************************************************/
/**************************************************************************
 *
 * SOURCE FILE NAME = LOCKDDC.C
 *
 * DESCRIPTIVE NAME = PLOTTER DRIVER SOURCE FILE
 *
 * Copyright :
 *
 *
 * VERSION =
 *
 * DATE               05/25/93
 *
 * DESCRIPTION=PLOTTER DRIVER SOURCE-This file contains the lock and unlock
 *             code for the driver's instance data.
 *
 *
 * FUNCTIONS   EnterDriver             Entry to a hooked GRE function
 *
 *             LeaveDriver             Exit from a hooked GRE function
 *
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/

#define  INCL_DOSSEMAPHORES
#define  INCL_DOSPROCESS
#define  INCL_DOSERRORS
#include "plotters.h"
#include "init.h"
#include "error.h"
#include "lockddc.h"

/***************************************************************************
 *
 * FUNCTION NAME = EnterDriver
 *
 * DESCRIPTION   = Protects the pDDC while it is in the driver
 *
 *
 * INPUT         = pDDc
 *
 *
 * OUTPUT        = 0 or 1
 *
 *
 *
 *
 * RETURN-NORMAL = 1
 *
 *
 *
 * RETURN-ERROR  = 0
 *
 *
 *
 **************************************************************************/

ULONG EnterDriver(PDDC pDDC)
{
    if (RAMSEMREQUEST32(&pDDC->fsrDDCLock) == NO_ERROR)
    {
       if (pDDC->ulLockCount)
       {
       /*
       **  See if this thread ID matches the active thread ID in the pDDC
       */
           if ((USHORT)pDDC->tidThreadID != pDDC->fsrDDCLock.ThrdID)
           {
               GplErrSetError(PMERR_HDC_BUSY);
               RAMSEMCLEAR32(&pDDC->fsrDDCLock);
               return(FALSE);
           }
       }
       /*
       ** pDDC is not busy so grab it
       */
       else
       {
           pDDC->tidThreadID = pDDC->fsrDDCLock.ThrdID;
       }

       pDDC->ulLockCount++;
       /*
       ** We were able to grab the semaphore.  We only want to do a
       ** DosReleaseMutexSem when we were able to grab the sem.  Otherwise at
       ** this point the same thread ID is in the DC data and we were not able
       ** to grab the semaphore, but got an ERROR_TIMEOUT.  So we should not
       ** Release the semaphore.
       */
       RAMSEMCLEAR32(&pDDC->fsrDDCLock);
    }
    else
    {
       GplErrSetError(PMERR_HDC_BUSY);
       return(FALSE);
    }
    return(TRUE);
}

/***************************************************************************
 *
 * FUNCTION NAME = LeaveDriver
 *
 *
 * DESCRIPTION   = Works with EnterDriver to ensure that threads with
 *                 different IDs are not accessing the same pDDC
 *
 *
 * INPUT         = pDDc
 *
 * OUTPUT        = NONE
 *
 * RETURN-NORMAL = NONE
 *
 * RETURN-ERROR  = NONE
 *
 **************************************************************************/
VOID LeaveDriver(PDDC pDDC)
{
    if (RAMSEMREQUEST32(&pDDC->fsrDDCLock) == NO_ERROR)
    {
       --(pDDC->ulLockCount);
       if (pDDC->ulLockCount < 0)
       {
            /* C/Set2 conversion DEBUG */
            //Int3();
       }
       RAMSEMCLEAR32(&pDDC->fsrDDCLock);
     }
     else
     {
       //Int3();
     }
}


LONG InitFSRSem(PFSRSEM pfsrDDCLock)
{
    pfsrDDCLock->Length= sizeof(FSRSEM);
    pfsrDDCLock->ProcID = 0;
    pfsrDDCLock->ThrdID = 0;
    pfsrDDCLock->Usage  = 0;
    pfsrDDCLock->Client = 0;
    pfsrDDCLock->Timeout= 6000;  /* 6 seconds time out */
    pfsrDDCLock->RAMsem = 0;
    return(NO_ERROR);
}
