Figure 4: Using the priority semaphore in a multithreaded server

#include "PrioritySemaphore.h"

// Declare a priority semaphore so that it is in scope for all
// database access, preferably as a member of some class.
CPrioritySemaphore psemDbAccessSemaphore;

// Initialize the semaphore before the first database access,
// typically in a constructor.
if( ! psemDbAccessSemaphore.Create(
         nNumPriorityLevels,   // nNumPriorityLevels == 2 
                               // in this case
         nNumDataBaseLicenses, // initial count
         nNumDataBaseLicenses  // maximal count
         ) ) 
{
   // fatal
}

// If a client request is "lightweight," the serving thread 
// performs a wait operation with high priority.
DWORD dwRetVal = psemDbAccessSemaphore.Wait(
   enumHighPriority,     // enumHighPriority = 1
   dwHighPriorityTimeout // timeout in ms
   );

if( WAIT_TIMEOUT == dwRetVal )
{
   // Notify client of timeout
}
else if ( WAIT_FAILED == dwRetVal )
{
   // fatal
}
else if ( WAIT_OBJECT_0 == dwRetVal )
{
   //
   // serve client
   //

   // Release the semaphore. If the code that serves the 
   // client throws exceptions, release the semaphore in the 
   // catch block as well.
   LONG lPreviousCount;
   if( ! psemDbAccessSemaphore.Release(1, &lPreviousCount) )
   {
      ASSERT( ERROR_TOO_MANY_POSTS != GetLastError() );
      // fatal
   }

}
else 
   ASSERT( FALSE );

   // If a client request is "heavyweight," the serving thread 
   // performs essentially the same code as above, except this 
   // time the wait operation uses low priority.