Skip to content

Commit 8dc7d17

Browse files
committed
NetworkGroup thread safety
1 parent 250cdc6 commit 8dc7d17

1 file changed

Lines changed: 32 additions & 30 deletions

File tree

LibreHardwareMonitorLib/Hardware/Network/NetworkGroup.cs

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@ internal class NetworkGroup : IGroup, IHardwareChanged
1616
public event HardwareEventHandler HardwareAdded;
1717
public event HardwareEventHandler HardwareRemoved;
1818

19-
private readonly Dictionary<string, Network> _networks = new();
20-
private readonly object _scanLock = new();
19+
private readonly object _updateLock = new();
2120
private readonly ISettings _settings;
22-
private readonly List<Network> _hardware = new();
21+
private List<Network> _hardware = [];
2322

2423
public NetworkGroup(ISettings settings)
2524
{
@@ -66,48 +65,50 @@ private void UpdateNetworkInterfaces(ISettings settings)
6665
{
6766
// When multiple events fire concurrently, we don't want threads interfering
6867
// with others as they manipulate non-thread safe state.
69-
lock (_scanLock)
68+
lock (_updateLock)
7069
{
71-
IOrderedEnumerable<NetworkInterface> networkInterfaces = GetNetworkInterfaces();
70+
List<NetworkInterface> networkInterfaces = GetNetworkInterfaces();
7271
if (networkInterfaces == null)
7372
return;
7473

75-
var foundNetworkInterfaces = networkInterfaces.ToDictionary(x => x.Id, x => x);
74+
List<Network> removables = [];
75+
List<Network> additions = [];
76+
77+
List<Network> hardware = [.. _hardware];
7678

7779
// Remove network interfaces that no longer exist.
78-
List<string> removeKeys = new();
79-
foreach (KeyValuePair<string, Network> networkInterfacePair in _networks)
80+
for (int i = 0; i < hardware.Count; i++)
8081
{
81-
if (foundNetworkInterfaces.ContainsKey(networkInterfacePair.Key))
82+
Network network = hardware[i];
83+
if (networkInterfaces.Any(x => x.Id == network.NetworkInterface.Id))
8284
continue;
8385

84-
removeKeys.Add(networkInterfacePair.Key);
85-
}
86-
87-
foreach (string key in removeKeys)
88-
{
89-
Network network = _networks[key];
90-
network.Close();
91-
_networks.Remove(key);
92-
93-
_hardware.Remove(network);
94-
HardwareRemoved?.Invoke(network);
86+
hardware.RemoveAt(i--);
87+
removables.Add(network);
9588
}
9689

97-
// Add new network interfaces.
98-
foreach (KeyValuePair<string, NetworkInterface> networkInterfacePair in foundNetworkInterfaces)
90+
// Add new ones.
91+
foreach (NetworkInterface networkInterface in networkInterfaces)
9992
{
100-
if (!_networks.ContainsKey(networkInterfacePair.Key))
93+
if (hardware.All(x => x.NetworkInterface.Id != networkInterface.Id))
10194
{
102-
_networks.Add(networkInterfacePair.Key, new Network(networkInterfacePair.Value, settings));
103-
_hardware.Add(_networks[networkInterfacePair.Key]);
104-
HardwareAdded?.Invoke(_networks[networkInterfacePair.Key]);
95+
Network network = new(networkInterface, settings);
96+
hardware.Add(network);
97+
additions.Add(network);
10598
}
10699
}
100+
101+
_hardware = hardware;
102+
103+
foreach (Network removable in removables)
104+
HardwareRemoved?.Invoke(removable);
105+
106+
foreach (Network addition in additions)
107+
HardwareAdded?.Invoke(addition);
107108
}
108109
}
109110

110-
private static IOrderedEnumerable<NetworkInterface> GetNetworkInterfaces()
111+
private static List<NetworkInterface> GetNetworkInterfaces()
111112
{
112113
int retry = 0;
113114

@@ -116,8 +117,9 @@ private static IOrderedEnumerable<NetworkInterface> GetNetworkInterfaces()
116117
try
117118
{
118119
return NetworkInterface.GetAllNetworkInterfaces()
119-
.Where(DesiredNetworkType)
120-
.OrderBy(x => x.Name);
120+
.Where(IsDesiredNetworkType)
121+
.OrderBy(static x => x.Name)
122+
.ToList();
121123
}
122124
catch (NetworkInformationException)
123125
{
@@ -134,7 +136,7 @@ private void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
134136
UpdateNetworkInterfaces(_settings);
135137
}
136138

137-
private static bool DesiredNetworkType(NetworkInterface nic)
139+
private static bool IsDesiredNetworkType(NetworkInterface nic)
138140
{
139141
switch (nic.NetworkInterfaceType)
140142
{

0 commit comments

Comments
 (0)