Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 83 additions & 82 deletions src/KNXLib/KnxLockManager.cs
Original file line number Diff line number Diff line change
@@ -1,86 +1,87 @@
using System;
using System.Threading;

namespace KNXLib
{
internal class KnxLockManager
{
private readonly SemaphoreSlim _sendLock = new SemaphoreSlim(0);
private readonly object _connectedLock = new object();
private bool _isConnected;

internal int IntervalMs { get; set; } = 200;

public int LockCount
{
get { return _sendLock.CurrentCount; }
}

public void LockConnection()
{
lock (_connectedLock)
{
if (!_isConnected)
return;

SendLock();
_isConnected = false;
}
}

public void UnlockConnection()
{
lock (_connectedLock)
{
if (_isConnected)
return;

_isConnected = true;
SendUnlock();
}
}

public void PerformLockedOperation(Action action)
{
// TODO: Shouldn't this check if we are connected?

try
{
SendLock();
action();
}
finally
{
SendUnlockPause();
}
}

private void SendLock()
{
_sendLock.Wait();
}

private void SendUnlock()
{
_sendLock.Release();
}

private void SendUnlockPause()
{
using System;
using System.Threading;

namespace KNXLib
{
internal class KnxLockManager
{
private readonly SemaphoreSlim _sendLock = new SemaphoreSlim(0);
private readonly object _connectedLock = new object();
private bool _isConnected;

internal int IntervalMs { get; set; } = 200;

public int LockCount
{
get { return _sendLock.CurrentCount; }
}

public void LockConnection()
{
lock (_connectedLock)
{
if (!_isConnected)
return;

SendLock();
_isConnected = false;
}
}

public void UnlockConnection()
{
lock (_connectedLock)
{
if (_isConnected)
return;

_isConnected = true;
SendUnlock();
}
}

public void PerformLockedOperation(Action action)
{
if (!_isConnected)
throw new InvalidOperationException("Unable to perform action: KNX is not connected.");

try
{
SendLock();
action();
}
finally
{
SendUnlockPause();
}
}

private void SendLock()
{
_sendLock.Wait();
}

private void SendUnlock()
{
_sendLock.Release();
}

private void SendUnlockPause()
{
if (IntervalMs == 0)
{
_sendLock.Release();
_sendLock.Release();
return;
}

var t = new Thread(SendUnlockPauseThread) { IsBackground = true };
t.Start();
}

private void SendUnlockPauseThread()
{
Thread.Sleep(IntervalMs);
_sendLock.Release();
}
}
}
var t = new Thread(SendUnlockPauseThread) { IsBackground = true };
t.Start();
}
private void SendUnlockPauseThread()
{
Thread.Sleep(IntervalMs);
_sendLock.Release();
}
}
}