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.