--- q_a/samples/readwrit/database.c 2018/08/09 18:29:19 1.1 +++ q_a/samples/readwrit/database.c 2018/08/09 18:29:56 1.1.1.3 @@ -1,3 +1,54 @@ + +/******************************************************************************\ +* This is a part of the Microsoft Source Code Samples. +* Copyright (C) 1993 Microsoft Corporation. +* All rights reserved. +* This source code is only intended as a supplement to +* Microsoft Development Tools and/or WinHelp documentation. +* See these sources for detailed information regarding the +* Microsoft samples programs. +\******************************************************************************/ + +/****************************************************************************\ +** MODULE: DataBase ** +** ** +** ** +** PURPOSE: Demonstrates the basic concepts of one of the classical ** +** synchronous problems. A derivative of the Reader/Writer ** +** problem. In which one must allow access to each without ** +** jeopardizing the Database. ** +** ** +** INTERNAL FUNCTIONS: ** +** ** +** InitializeDataBase ** +** CloseDataBase ** +** InitializeSubsystem ** +** InitApp ** +** CleanupSubsystem ** +** CleanupApp ** +** TestInitExitPoint ** +** ErrorMsg ** +** DebugMsg ** +** ** +** ** +** EXPORTED FUNCTIONS ** +** ** +** ReadDataBase ** +** WriteDataBase ** +** ** +** ** +** COMMENTS: ** +** ** +** This also demonstrates how to have both global shared data ** +** instance data. What I've done is named the shared section ** +** with the #pragma data_seg( SEGNAME) statement and ** +** referenced this in the DEF file as READ/WRITE/SHARED. ** +** ** +\***************************************************************************/ + + + + #define STRICT #define NOMINMAX #include @@ -25,7 +76,21 @@ typedef HANDLE HEVENT ; /*global Variables */ + + +/* Put gUserCount in a GLOBAL section. This is because first time + * initialization is handled differently than others + */ + +#pragma data_seg("MYSEG") + int gUserCount = 0 ; + +#pragma data_seg(".data") + + + + HMUTEX ghMutex ; HSEM ghSemaphore ; HEVENT ghReadEvent1, ghReadEvent2, ghWriteEvent1, ghWriteEvent2 ; @@ -56,7 +121,7 @@ BOOL PutData ( PSZ psz ) ; /***** DLL Entry/Exit point *****/ -BOOL APIENTRY DLLInitExitPoint ( HANDLE hModule, DWORD dwReason, LPVOID lpReserved ) ; +BOOL APIENTRY DllMain ( HANDLE hModule, DWORD dwReason, LPVOID lpReserved ) ; /***** Debuging functions *****/ @@ -66,49 +131,6 @@ VOID DebugMsg ( PSZ psz ) ; -/***** Public functions *****/ - -BOOL APIENTRY ReadDataBase ( PSZ, PSZ ) ; -BOOL APIENTRY WriteDataBase ( PSZ, PSZ ) ; - - - - - -/***************************************************************************\ -** ** -** PROGRAM: DataBase ** -** ** -** PURPOSE: Demonstrates the basic concepts of one of the classical ** -** synchronous problems. A derivative of the Reader/Writer ** -** problem. In which one must allow access to each without ** -** jeopardizing the Database. ** -** ** -** INTERNAL FUNCTIONS: ** -** ** -** InitializeDataBase ** -** CloseDataBase ** -** InitializeSubsystem ** -** InitApp ** -** CleanupSubsystem ** -** CleanupApp ** -** TestInitExitPoint ** -** ErrorMsg ** -** DebugMsg ** -** ** -** ** -** EXPORTED FUNCTIONS ** -** ** -** ReadDataBase ** -** WriteDataBase ** -** ** -** ** -** COMMENTS: ** -** ** -** Currently this ** -** ** -\***************************************************************************/ - /***************************************************************************\ @@ -144,7 +166,7 @@ VOID ErrorMsg ( PSZ psz ) \****************************************************************************/ -VOID APIENTRY DebugMsg ( PSZ psz ) +VOID DebugMsg ( PSZ psz ) { printf ( psz ) ; } @@ -152,7 +174,7 @@ VOID APIENTRY DebugMsg ( PSZ psz ) /***************************************************************************\ ** ** -** FUNCTION: DLLInitExitPoint ** +** FUNCTION: DllMain ** ** ** ** PURPOSE: Handles both initialization and cleanup of DLL ** ** ** @@ -173,7 +195,7 @@ VOID APIENTRY DebugMsg ( PSZ psz ) -BOOL APIENTRY DLLInitExitPoint ( HANDLE hModule, DWORD dwReason, LPVOID lpReserved ) +BOOL APIENTRY DllMain ( HANDLE hModule, DWORD dwReason, LPVOID lpReserved ) { BOOL bSuccess ; @@ -185,7 +207,6 @@ BOOL APIENTRY DLLInitExitPoint ( HANDLE gUserCount++ ; - printf ( "\nInitializing subsystem" ) ; printf ( "\nNumber of clients currently using this are %d\n", gUserCount ) ; if ( gUserCount == 1 ) @@ -563,7 +584,7 @@ BOOL APIENTRY ReadDataBase ( PSZ psz1, cReadQueueEx++ ; dwSuccess = SIGNALED ; - if ( cWriteQueue ) // Block if Writer waiting + if ( cWriteQueue ) // Block if Writer waiting dwSuccess = WaitForSingleObject ( ghReadEvent1, 0xFFFFFFFF ) ; // dwSuccess = WaitForSingleObject ( ghReadEvent1, 5000 ) ; @@ -583,14 +604,14 @@ BOOL APIENTRY ReadDataBase ( PSZ psz1, switch ( WaitForSingleObject ( ghSemaphore, 0xFFFFFFFF ) ) // switch ( WaitForSingleObject ( ghSemaphore, 3000 ) ) { - case SIGNALED: - try { - if ( InWrite ) // Block if Writer in database - dwSuccess = WaitForSingleObject ( ghReadEvent2, 0xFFFFFFFF ) ; -// dwSuccess = WaitForSingleObject ( ghReadEvent2, 1500 ) ; + case SIGNALED: + __try { + if ( InWrite ) // Block if Writer in database + dwSuccess = WaitForSingleObject ( ghReadEvent2, 0xFFFFFFFF ) ; +// dwSuccess = WaitForSingleObject ( ghReadEvent2, 1500 ) ; - cRead++ ; // Number readers in database - cReadQueue-- ; // Reader leaving queue + cRead++ ; // Number readers in database + cReadQueue-- ; // Reader leaving queue /* * Signal Writer if no Reader waiting @@ -599,10 +620,10 @@ BOOL APIENTRY ReadDataBase ( PSZ psz1, if ( !cReadQueue ) bSuccess = SetEvent ( ghWriteEvent1 ) ; - if ( dwSuccess == SIGNALED ) - { - bSuccess = GetData ( psz1 ) ; // Read data - cRead-- ; + if ( dwSuccess == SIGNALED ) + { + bSuccess = GetData ( psz1 ) ; // Read data + cRead-- ; /* * Signal Writer if no Reader in database * @@ -611,13 +632,13 @@ BOOL APIENTRY ReadDataBase ( PSZ psz1, if ( !cRead ) bSuccess = SetEvent ( ghWriteEvent2 ) ; - ReleaseSemaphore ( ghSemaphore, // Let next waiting - 1, // reader in the queue - NULL ) ; - } - else - { - cRead-- ; + ReleaseSemaphore ( ghSemaphore, // Let next waiting + 1, // reader in the queue + NULL ) ; + } + else + { + cRead-- ; /* * Signal Writer if no Reader in database * @@ -626,11 +647,11 @@ BOOL APIENTRY ReadDataBase ( PSZ psz1, if ( !cRead ) bSuccess = SetEvent ( ghWriteEvent2 ) ; - bSuccess = FALSE ; - DebugMsg ( "ReadDataBase: Error Waiting for ghReadEvent2\n" ) ; - } - } - finally { + bSuccess = FALSE ; + DebugMsg ( "ReadDataBase: Error Waiting for ghReadEvent2\n" ) ; + } + } + __finally { // what if these is already decremented above???? cRead-- ; /* @@ -648,19 +669,19 @@ BOOL APIENTRY ReadDataBase ( PSZ psz1, if ( !cReadQueue ) bSuccess = SetEvent ( ghWriteEvent1 ) ; - bSuccess = FALSE ; - ReleaseSemaphore ( ghSemaphore, // Let next waiting - 1, // reader in the queue - NULL ) ; - } + bSuccess = FALSE ; + ReleaseSemaphore ( ghSemaphore, // Let next waiting + 1, // reader in the queue + NULL ) ; + } - break ; + break ; - case WAIT_TIMEOUT: - DebugMsg ( "ReadDataBase: Error WAIT_TIMEOUT ghSemaphore\n" ) ; + case WAIT_TIMEOUT: + DebugMsg ( "ReadDataBase: Error WAIT_TIMEOUT ghSemaphore\n" ) ; //where to put this? - cReadQueue-- ; // Reader leaving queue + cReadQueue-- ; // Reader leaving queue /* * Signal Writer if no Reader waiting * @@ -668,14 +689,14 @@ BOOL APIENTRY ReadDataBase ( PSZ psz1, if ( !cReadQueue ) bSuccess = SetEvent ( ghWriteEvent1 ) ; - bSuccess = FALSE ; - break ; + bSuccess = FALSE ; + break ; - case WAIT_ERROR: - ErrorMsg ( "ReadDataBase: Error WAIT_ERROR ghSemaphore" ) ; + case WAIT_ERROR: + ErrorMsg ( "ReadDataBase: Error WAIT_ERROR ghSemaphore" ) ; //where to put this? - cReadQueue-- ; // Reader leaving queue + cReadQueue-- ; // Reader leaving queue /* * Signal Writer if no Reader waiting * @@ -683,14 +704,14 @@ BOOL APIENTRY ReadDataBase ( PSZ psz1, if ( !cReadQueue ) bSuccess = SetEvent ( ghWriteEvent1 ) ; - bSuccess = FALSE ; - break ; + bSuccess = FALSE ; + break ; - default: - DebugMsg ( "ReadDataBase: Dropped through switch\n" ) ; + default: + DebugMsg ( "ReadDataBase: Dropped through switch\n" ) ; //where to put this? - cReadQueue-- ; // Reader leaving queue + cReadQueue-- ; // Reader leaving queue /* * Signal Writer if no Reader waiting * @@ -698,8 +719,8 @@ BOOL APIENTRY ReadDataBase ( PSZ psz1, if ( !cReadQueue ) bSuccess = SetEvent ( ghWriteEvent1 ) ; - bSuccess = FALSE ; - break ; + bSuccess = FALSE ; + break ; } } // END IF @@ -742,12 +763,12 @@ BOOL APIENTRY WriteDataBase ( PSZ psz1, // DebugMsg ( "In WriteDataBase\n" ) ; - cWriteQueue++ ; // Writer entering queue + cWriteQueue++ ; // Writer entering queue dwSuccess = SIGNALED ; - // should the same event be used twice ??? + // should the same event be used twice ??? - if ( cReadQueue ) // Block if Reader waiting + if ( cReadQueue ) // Block if Reader waiting dwSuccess = WaitForSingleObject ( ghWriteEvent1, 0xFFFFFFFF ) ; // dwSuccess = WaitForSingleObject ( ghWriteEvent1, 5000 ) ; @@ -764,9 +785,9 @@ BOOL APIENTRY WriteDataBase ( PSZ psz1, */ switch ( WaitForSingleObject ( ghMutex, 0xFFFFFFFF ) ) { // switch ( WaitForSingleObject ( ghMutex, 3000 ) ) { - case SIGNALED: - try { - InWrite = TRUE ; + case SIGNALED: + __try { + InWrite = TRUE ; cWriteQueue-- ; /* @@ -776,22 +797,22 @@ BOOL APIENTRY WriteDataBase ( PSZ psz1, if ( cReadQueueEx ) bSuccess = SetEvent ( ghReadEvent1 ) ; - // Writer leaving queue - if ( cRead ) // Block if Reader in database - dwSuccess = WaitForSingleObject ( ghWriteEvent2, 0xFFFFFFFF ) ; -// dwSuccess = WaitForSingleObject ( ghWriteEvent2, 1500 ) ; - - if ( dwSuccess == SIGNALED ) - { - bSuccess = PutData ( psz1 ) ; - InWrite = FALSE ; + // Writer leaving queue + if ( cRead ) // Block if Reader in database + dwSuccess = WaitForSingleObject ( ghWriteEvent2, 0xFFFFFFFF ) ; +// dwSuccess = WaitForSingleObject ( ghWriteEvent2, 1500 ) ; + + if ( dwSuccess == SIGNALED ) + { + bSuccess = PutData ( psz1 ) ; + InWrite = FALSE ; /* * Signal Reader when no Writer waiting * */ bSuccess = SetEvent ( ghReadEvent2 ) ; - ReleaseMutex ( ghMutex ) ; // Let next waiting writer in the queue - } + ReleaseMutex ( ghMutex ) ; // Let next waiting writer in the queue + } else { bSuccess = FALSE ; @@ -803,9 +824,9 @@ BOOL APIENTRY WriteDataBase ( PSZ psz1, bSuccess = SetEvent ( ghReadEvent2 ) ; DebugMsg ( "WriteDataBase: Error Waiting on ghWriteEvent2\n" ) ; } - } - finally { - InWrite = FALSE ; + } + __finally { + InWrite = FALSE ; /* * Signal Reader after leaving database * @@ -820,12 +841,12 @@ BOOL APIENTRY WriteDataBase ( PSZ psz1, bSuccess = SetEvent ( ghReadEvent1 ) ; bSuccess = FALSE ; - ReleaseMutex ( ghMutex ) ; - } - break ; + ReleaseMutex ( ghMutex ) ; + } + break ; - case WAIT_TIMEOUT: - DebugMsg ( "WriteDataBase: Error WAIT_TIMEOUT ghMutex\n" ) ; + case WAIT_TIMEOUT: + DebugMsg ( "WriteDataBase: Error WAIT_TIMEOUT ghMutex\n" ) ; cWriteQueue-- ; /* * Signal Reader if no Writer waiting @@ -834,11 +855,11 @@ BOOL APIENTRY WriteDataBase ( PSZ psz1, if ( !cWriteQueue ) bSuccess = SetEvent ( ghReadEvent1 ) ; - bSuccess = FALSE ; - break ; + bSuccess = FALSE ; + break ; - case WAIT_ABANDONED: - DebugMsg ( "WriteDataBase: Error WAIT_ABANDONED ghMutex\n" ) ; + case WAIT_ABANDONED: + DebugMsg ( "WriteDataBase: Error WAIT_ABANDONED ghMutex\n" ) ; cWriteQueue-- ; /* * Signal Reader if no Writer waiting @@ -847,11 +868,11 @@ BOOL APIENTRY WriteDataBase ( PSZ psz1, if ( !cWriteQueue ) bSuccess = SetEvent ( ghReadEvent1 ) ; - bSuccess = FALSE ; - break ; + bSuccess = FALSE ; + break ; - case WAIT_ERROR: - ErrorMsg ( "WriteDataBase: Error WAIT_ERROR ghMutex" ) ; + case WAIT_ERROR: + ErrorMsg ( "WriteDataBase: Error WAIT_ERROR ghMutex" ) ; cWriteQueue-- ; /* * Signal Reader if no Writer waiting @@ -860,11 +881,11 @@ BOOL APIENTRY WriteDataBase ( PSZ psz1, if ( !cWriteQueue ) bSuccess = SetEvent ( ghReadEvent1 ) ; - bSuccess = FALSE ; - break ; + bSuccess = FALSE ; + break ; - default: - DebugMsg ( "WriteDataBase: Dropped through switch\n" ) ; + default: + DebugMsg ( "WriteDataBase: Dropped through switch\n" ) ; cWriteQueue-- ; /* * Signal Reader if no Writer waiting @@ -873,16 +894,16 @@ BOOL APIENTRY WriteDataBase ( PSZ psz1, if ( !cWriteQueue ) bSuccess = SetEvent ( ghReadEvent1 ) ; - bSuccess = FALSE ; - break ; + bSuccess = FALSE ; + break ; } } // END IF if ( cReadQueue ) - bSuccess = SetEvent ( ghReadEvent1 ) ; // Signal Reader + bSuccess = SetEvent ( ghReadEvent1 ) ; // Signal Reader else - bSuccess = SetEvent ( ghWriteEvent1 ) ; // Signal Writer + bSuccess = SetEvent ( ghWriteEvent1 ) ; // Signal Writer return ( bSuccess ) ; }