'Classes/ActiveBasic/Windows/CriticalSection.ab

Namespace ActiveBasic
Namespace Windows

Namespace Detail
	Const InterlockedExchangeAnyPointer(p, x) = InterlockedExchangePointer(ByVal VarPtr(p) As *VoidPtr, x)
End Namespace

Class CriticalSection
'	Inherits System.IDisposable
Public
	Sub CriticalSection()
		disposed = 0
		InitializeCriticalSection(cs)
	End Sub

	Sub ~CriticalSection()
		Dispose()
	End Sub

	/*Override*/ Sub Dispose()
		If InterlockedIncrement(disposed) = 0 Then
			DeleteCriticalSection(cs)
		End If
	End Sub

	Function Enter() As ActiveBasic.Windows.CriticalSectionLock
		Return New CriticalSectionLock(cs)
	End Function
Private
	cs As CRITICAL_SECTION
	disposed As Long
End Class

Class CriticalSectionLock
'	Inherits System.IDisposable
Public
	Sub CriticalSectionLock(ByRef cs As CRITICAL_SECTION)
		pcs = VarPtr(cs)
		EnterCriticalSection(cs)
	End Sub

	Sub ~CriticalSectionLock()
		Dispose()
	End Sub

	Sub Leave()
		Dispose()
	End Sub

	/*Override*/ Sub Dispose()
'		Dim pcsOld = ActiveBasic.Windows.Detail.InterlockedExchangeAnyPointer(pcs, 0)
		Dim pcsOld = InterlockedExchangePointer(pcs As VoidPtr, 0) As *CRITICAL_SECTION
		If pcsOld <> 0 Then
			LeaveCriticalSection(ByVal pcsOld)
		End If
	End Sub
Private
	pcs As *CRITICAL_SECTION
End Class

End Namespace 'Windows
End Namespace 'ActiveBasic
