Main Page   Modules   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

SWMRG.cpp

Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 Module:  SWMRG.cpp
00004 Notices: Copyright (c) 2000 Jeffrey Richter
00005 ******************************************************************************/
00006 
00007 
00008 #include "StdAfx.h"
00009 #include "SWMRG.h"
00010 
00011 
00013 
00014 
00015 CSWMRG::CSWMRG() {
00016 
00017    // Initially no readers want access, no writers want access, and 
00018    // no threads are accessing the resource
00019    m_nWaitingReaders = m_nWaitingWriters = m_nActive = 0;
00020    m_hsemReaders = CreateSemaphore(NULL, 0, MAXLONG, NULL);
00021    m_hsemWriters = CreateSemaphore(NULL, 0, MAXLONG, NULL);
00022    InitializeCriticalSection(&m_cs);
00023 }
00024 
00025 
00027 
00028 
00029 CSWMRG::~CSWMRG() {
00030 
00031 #ifdef _DEBUG
00032    // A SWMRG shouldn't be destroyed if any threads are using the resource
00033    if (m_nActive != 0)
00034       DebugBreak();
00035 #endif
00036 
00037    m_nWaitingReaders = m_nWaitingWriters = m_nActive = 0;
00038    DeleteCriticalSection(&m_cs);
00039    CloseHandle(m_hsemReaders);
00040    CloseHandle(m_hsemWriters);
00041 }
00042 
00043 
00045 
00046 
00047 VOID CSWMRG::WaitToRead() {
00048 
00049    // Ensure exclusive access to the member variables
00050    EnterCriticalSection(&m_cs);
00051 
00052    // Are there writers waiting or is a writer writing?
00053    BOOL fResourceWritePending = (m_nWaitingWriters || (m_nActive < 0));
00054 
00055    if (fResourceWritePending) {
00056 
00057       // This reader must wait, increment the count of waiting readers
00058       m_nWaitingReaders++;
00059    } else {
00060 
00061       // This reader can read, increment the count of active readers
00062       m_nActive++;
00063    }
00064 
00065    // Allow other threads to attempt reading/writing
00066    LeaveCriticalSection(&m_cs);
00067 
00068    if (fResourceWritePending) {
00069 
00070       // This thread must wait
00071       WaitForSingleObject(m_hsemReaders, INFINITE);
00072    }
00073 }
00074 
00075 
00077 
00078 
00079 VOID CSWMRG::WaitToWrite() {
00080 
00081    // Ensure exclusive access to the member variables
00082    EnterCriticalSection(&m_cs);
00083 
00084    // Are there any threads accessing the resource?
00085    BOOL fResourceOwned = (m_nActive != 0);
00086 
00087    if (fResourceOwned) {
00088 
00089       // This writer must wait, increment the count of waiting writers
00090       m_nWaitingWriters++;
00091    } else {
00092 
00093       // This writer can write, decrement the count of active writers
00094       m_nActive = -1;
00095    }
00096 
00097    // Allow other threads to attempt reading/writing
00098    LeaveCriticalSection(&m_cs);
00099 
00100    if (fResourceOwned) {
00101 
00102       // This thread must wait
00103       WaitForSingleObject(m_hsemWriters, INFINITE);
00104    }
00105 }
00106 
00107 
00109 
00110 
00111 VOID CSWMRG::Done() {
00112 
00113    // Ensure exclusive access to the member variables
00114    EnterCriticalSection(&m_cs);
00115 
00116    if (m_nActive > 0) {
00117 
00118       // Readers have control so a reader must be done
00119       m_nActive--;
00120    } else {
00121 
00122       // Writers have control so a writer must be done
00123       m_nActive++;
00124    }
00125 
00126    HANDLE hsem = NULL;  // Assume no threads are waiting
00127    LONG lCount = 1;     // Assume only 1 waiter wakes; always true for writers
00128 
00129    if (m_nActive == 0) {
00130 
00131       // No thread has access, who should wake up?
00132       // NOTE: It is possible that readers could never get access
00133       //       if there are always writers wanting to write
00134 
00135       if (m_nWaitingWriters > 0) {
00136 
00137          // Writers are waiting and they take priority over readers
00138          m_nActive = -1;         // A writer will get access
00139          m_nWaitingWriters--;    // One less writer will be waiting
00140          hsem = m_hsemWriters;   // Writers wait on this semaphore
00141          // NOTE: The semaphore will release only 1 writer thread
00142 
00143       } else if (m_nWaitingReaders > 0) {
00144 
00145          // Readers are waiting and no writers are waiting
00146          m_nActive = m_nWaitingReaders;   // All readers will get access
00147          m_nWaitingReaders = 0;           // No readers will be waiting
00148          hsem = m_hsemReaders;            // Readers wait on this semaphore
00149          lCount = m_nActive;              // Semaphore releases all readers
00150       } else {
00151 
00152          // There are no threads waiting at all; no semaphore gets released
00153       }
00154    }
00155 
00156    // Allow other threads to attempt reading/writing
00157    LeaveCriticalSection(&m_cs);
00158 
00159    if (hsem != NULL) {
00160 
00161       // Some threads are to be released
00162       ReleaseSemaphore(hsem, lCount, NULL);
00163    }
00164 }
00165 
00166 

Generated on Mon Mar 25 06:29:59 2002 for Window Dressing by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001