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.
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()
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
)
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
);
68 LeaveCriticalSection(&m_cs
);
75 bool CRWSection::WaitToWrite(DWORD waitTime
)
77 EnterCriticalSection(&m_cs
);
79 BOOL fResourceOwned
= (m_nActive
!= 0);
90 LeaveCriticalSection(&m_cs
);
94 if (WaitForSingleObject(m_hWriters
, waitTime
) != WAIT_OBJECT_0
)
96 EnterCriticalSection(&m_cs
);
98 LeaveCriticalSection(&m_cs
);
105 void CRWSection::Done()
107 EnterCriticalSection(&m_cs
);
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)
132 else if (m_nWaitingReaders
> 0)
134 m_nActive
= m_nWaitingReaders
;
135 m_nWaitingReaders
= 0;
141 // no threads waiting, nothing to do
145 LeaveCriticalSection(&m_cs
);
149 ReleaseSemaphore(hsem
, lCount
, NULL
);