00001
00002
00003
00004
00005
00006
00007
00008 #include "StdAfx.h"
00009 #include "SWMRG.h"
00010
00011
00013
00014
00015 CSWMRG::CSWMRG() {
00016
00017
00018
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
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
00050 EnterCriticalSection(&m_cs);
00051
00052
00053 BOOL fResourceWritePending = (m_nWaitingWriters || (m_nActive < 0));
00054
00055 if (fResourceWritePending) {
00056
00057
00058 m_nWaitingReaders++;
00059 } else {
00060
00061
00062 m_nActive++;
00063 }
00064
00065
00066 LeaveCriticalSection(&m_cs);
00067
00068 if (fResourceWritePending) {
00069
00070
00071 WaitForSingleObject(m_hsemReaders, INFINITE);
00072 }
00073 }
00074
00075
00077
00078
00079 VOID CSWMRG::WaitToWrite() {
00080
00081
00082 EnterCriticalSection(&m_cs);
00083
00084
00085 BOOL fResourceOwned = (m_nActive != 0);
00086
00087 if (fResourceOwned) {
00088
00089
00090 m_nWaitingWriters++;
00091 } else {
00092
00093
00094 m_nActive = -1;
00095 }
00096
00097
00098 LeaveCriticalSection(&m_cs);
00099
00100 if (fResourceOwned) {
00101
00102
00103 WaitForSingleObject(m_hsemWriters, INFINITE);
00104 }
00105 }
00106
00107
00109
00110
00111 VOID CSWMRG::Done() {
00112
00113
00114 EnterCriticalSection(&m_cs);
00115
00116 if (m_nActive > 0) {
00117
00118
00119 m_nActive--;
00120 } else {
00121
00122
00123 m_nActive++;
00124 }
00125
00126 HANDLE hsem = NULL;
00127 LONG lCount = 1;
00128
00129 if (m_nActive == 0) {
00130
00131
00132
00133
00134
00135 if (m_nWaitingWriters > 0) {
00136
00137
00138 m_nActive = -1;
00139 m_nWaitingWriters--;
00140 hsem = m_hsemWriters;
00141
00142
00143 } else if (m_nWaitingReaders > 0) {
00144
00145
00146 m_nActive = m_nWaitingReaders;
00147 m_nWaitingReaders = 0;
00148 hsem = m_hsemReaders;
00149 lCount = m_nActive;
00150 } else {
00151
00152
00153 }
00154 }
00155
00156
00157 LeaveCriticalSection(&m_cs);
00158
00159 if (hsem != NULL) {
00160
00161
00162 ReleaseSemaphore(hsem, lCount, NULL);
00163 }
00164 }
00165
00166