cleanup
[TortoiseGit.git] / src / Utils / RWSection.cpp
blobf8e53bbbad9f2867e0a10edef5ceb8581be99815
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2003-2008 - TortoiseSVN
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #include "StdAfx.h"
20 #include "RWSection.h"
22 CRWSection::CRWSection()
24 m_nWaitingReaders = m_nWaitingWriters = m_nActive = 0;
25 m_hReaders = CreateSemaphore(NULL, 0, MAXLONG, NULL);
26 m_hWriters = CreateSemaphore(NULL, 0, MAXLONG, NULL);
27 InitializeCriticalSection(&m_cs);
30 CRWSection::~CRWSection()
32 #ifdef _DEBUG
33 if (m_nActive > 0)
34 DebugBreak();
35 #endif
37 m_nWaitingReaders = m_nWaitingWriters = m_nActive = 0;
38 DeleteCriticalSection(&m_cs);
39 CloseHandle(m_hWriters);
40 CloseHandle(m_hReaders);
43 bool CRWSection::WaitToRead(DWORD waitTime)
45 EnterCriticalSection(&m_cs);
47 // Writers have priority
48 BOOL fResourceWritePending = (m_nWaitingWriters || (m_nActive < 0));
50 if (fResourceWritePending)
52 m_nWaitingReaders++;
54 else
56 m_nActive++;
59 LeaveCriticalSection(&m_cs);
61 if (fResourceWritePending)
63 // wait until writer is finished
64 if (WaitForSingleObject(m_hReaders, waitTime) != WAIT_OBJECT_0)
66 EnterCriticalSection(&m_cs);
67 m_nWaitingReaders--;
68 LeaveCriticalSection(&m_cs);
69 return false;
72 return true;
75 bool CRWSection::WaitToWrite(DWORD waitTime)
77 EnterCriticalSection(&m_cs);
79 BOOL fResourceOwned = (m_nActive != 0);
81 if (fResourceOwned)
83 m_nWaitingWriters++;
85 else
87 m_nActive = -1;
90 LeaveCriticalSection(&m_cs);
92 if (fResourceOwned)
94 if (WaitForSingleObject(m_hWriters, waitTime) != WAIT_OBJECT_0)
96 EnterCriticalSection(&m_cs);
97 m_nWaitingWriters--;
98 LeaveCriticalSection(&m_cs);
99 return false;
102 return true;
105 void CRWSection::Done()
107 EnterCriticalSection(&m_cs);
109 if (m_nActive > 0)
111 m_nActive--;
113 else
115 m_nActive++;
118 HANDLE hsem = NULL;
119 LONG lCount = 1;
121 if (m_nActive == 0)
123 // Note: If there are always writers waiting, then
124 // it's possible that a reader never gets access
125 // (reader starvation)
126 if (m_nWaitingWriters > 0)
128 m_nActive = -1;
129 m_nWaitingWriters--;
130 hsem = m_hWriters;
132 else if (m_nWaitingReaders > 0)
134 m_nActive = m_nWaitingReaders;
135 m_nWaitingReaders = 0;
136 hsem = m_hReaders;
137 lCount = m_nActive;
139 else
141 // no threads waiting, nothing to do
145 LeaveCriticalSection(&m_cs);
147 if (hsem != NULL)
149 ReleaseSemaphore(hsem, lCount, NULL);