mirror of
https://github.com/cemu-project/DS4Windows.git
synced 2024-12-26 16:41:50 +01:00
Added locking on a collection to clear up potential thread safety issues
Haven't encountered it myself but it does look like it could have been possible
This commit is contained in:
parent
74ea3e674f
commit
91c09c025a
@ -1,7 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Data;
|
using System.Windows.Data;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
@ -11,7 +13,8 @@ namespace DS4WinWPF.DS4Forms.ViewModels
|
|||||||
{
|
{
|
||||||
public class ControllerListViewModel
|
public class ControllerListViewModel
|
||||||
{
|
{
|
||||||
private object _colLockobj = new object();
|
//private object _colLockobj = new object();
|
||||||
|
private ReaderWriterLockSlim _colListLocker = new ReaderWriterLockSlim();
|
||||||
private ObservableCollection<CompositeDeviceModel> controllerCol =
|
private ObservableCollection<CompositeDeviceModel> controllerCol =
|
||||||
new ObservableCollection<CompositeDeviceModel>();
|
new ObservableCollection<CompositeDeviceModel>();
|
||||||
private Dictionary<int, CompositeDeviceModel> controllerDict =
|
private Dictionary<int, CompositeDeviceModel> controllerDict =
|
||||||
@ -56,27 +59,60 @@ namespace DS4WinWPF.DS4Forms.ViewModels
|
|||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
BindingOperations.EnableCollectionSynchronization(controllerCol, _colLockobj);
|
//BindingOperations.EnableCollectionSynchronization(controllerCol, _colLockobj);
|
||||||
|
BindingOperations.EnableCollectionSynchronization(controllerCol, _colListLocker,
|
||||||
|
ColLockCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ColLockCallback(IEnumerable collection, object context,
|
||||||
|
Action accessMethod, bool writeAccess)
|
||||||
|
{
|
||||||
|
if (writeAccess)
|
||||||
|
{
|
||||||
|
_colListLocker.EnterWriteLock();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_colListLocker.EnterReadLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
accessMethod?.Invoke();
|
||||||
|
|
||||||
|
if (writeAccess)
|
||||||
|
{
|
||||||
|
_colListLocker.ExitWriteLock();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_colListLocker.ExitReadLock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Service_HotplugController(ControlService sender, DS4Device device, int index)
|
private void Service_HotplugController(ControlService sender, DS4Device device, int index)
|
||||||
{
|
{
|
||||||
CompositeDeviceModel temp = new CompositeDeviceModel(device,
|
CompositeDeviceModel temp = new CompositeDeviceModel(device,
|
||||||
index, Global.ProfilePath[index], profileListHolder);
|
index, Global.ProfilePath[index], profileListHolder);
|
||||||
|
_colListLocker.EnterWriteLock();
|
||||||
controllerCol.Add(temp);
|
controllerCol.Add(temp);
|
||||||
controllerDict.Add(index, temp);
|
controllerDict.Add(index, temp);
|
||||||
|
_colListLocker.ExitWriteLock();
|
||||||
|
|
||||||
device.Removal += Controller_Removal;
|
device.Removal += Controller_Removal;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClearControllerList(object sender, EventArgs e)
|
private void ClearControllerList(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
_colListLocker.EnterReadLock();
|
||||||
foreach (CompositeDeviceModel temp in controllerCol)
|
foreach (CompositeDeviceModel temp in controllerCol)
|
||||||
{
|
{
|
||||||
temp.Device.Removal -= Controller_Removal;
|
temp.Device.Removal -= Controller_Removal;
|
||||||
}
|
}
|
||||||
|
_colListLocker.ExitReadLock();
|
||||||
|
|
||||||
|
_colListLocker.EnterWriteLock();
|
||||||
controllerCol.Clear();
|
controllerCol.Clear();
|
||||||
controllerDict.Clear();
|
controllerDict.Clear();
|
||||||
|
_colListLocker.ExitWriteLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ControllersChanged(object sender, EventArgs e)
|
private void ControllersChanged(object sender, EventArgs e)
|
||||||
@ -85,7 +121,8 @@ namespace DS4WinWPF.DS4Forms.ViewModels
|
|||||||
foreach (DS4Device currentDev in controlService.slotManager.ControllerColl)
|
foreach (DS4Device currentDev in controlService.slotManager.ControllerColl)
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
foreach(CompositeDeviceModel temp in controllerCol)
|
_colListLocker.EnterReadLock();
|
||||||
|
foreach (CompositeDeviceModel temp in controllerCol)
|
||||||
{
|
{
|
||||||
if (temp.Device == currentDev)
|
if (temp.Device == currentDev)
|
||||||
{
|
{
|
||||||
@ -93,16 +130,20 @@ namespace DS4WinWPF.DS4Forms.ViewModels
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_colListLocker.ExitReadLock();
|
||||||
|
|
||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
//int idx = controllerCol.Count;
|
//int idx = controllerCol.Count;
|
||||||
|
_colListLocker.EnterWriteLock();
|
||||||
int idx = controlService.slotManager.ReverseControllerDict[currentDev];
|
int idx = controlService.slotManager.ReverseControllerDict[currentDev];
|
||||||
CompositeDeviceModel temp = new CompositeDeviceModel(currentDev,
|
CompositeDeviceModel temp = new CompositeDeviceModel(currentDev,
|
||||||
idx, Global.ProfilePath[idx], profileListHolder);
|
idx, Global.ProfilePath[idx], profileListHolder);
|
||||||
controllerCol.Add(temp);
|
controllerCol.Add(temp);
|
||||||
controllerDict.Add(idx, temp);
|
controllerDict.Add(idx, temp);
|
||||||
|
_colListLocker.ExitWriteLock();
|
||||||
|
|
||||||
currentDev.Removal += Controller_Removal;
|
currentDev.Removal += Controller_Removal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,6 +152,7 @@ namespace DS4WinWPF.DS4Forms.ViewModels
|
|||||||
private void Controller_Removal(object sender, EventArgs e)
|
private void Controller_Removal(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
DS4Device currentDev = sender as DS4Device;
|
DS4Device currentDev = sender as DS4Device;
|
||||||
|
_colListLocker.EnterReadLock();
|
||||||
foreach (CompositeDeviceModel temp in controllerCol)
|
foreach (CompositeDeviceModel temp in controllerCol)
|
||||||
{
|
{
|
||||||
if (temp.Device == currentDev)
|
if (temp.Device == currentDev)
|
||||||
@ -120,6 +162,7 @@ namespace DS4WinWPF.DS4Forms.ViewModels
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_colListLocker.ExitReadLock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user