diff --git a/extension.js b/extension.js index 8ab9550..7c31dcc 100644 --- a/extension.js +++ b/extension.js @@ -570,6 +570,17 @@ var VitalsMenuButton = GObject.registerClass({ if (/^network-(?!rx$|tx$)/.test(typeKey)) typeKey = 'network'; let key = '_' + typeKey + '_' + label.replaceAll(' ', '_').toLowerCase() + '_'; + // issue #557 - interface is gone, drop it rather than show its last reading + if (value == 'destroy') { + this._values.removeNetworkSensor(key, label, type.replace('network-', '')); + if (key in this._sensorMenuItems) { + this._sensorMenuItems[key].destroy(); + delete this._sensorMenuItems[key]; + } + this._removeHotItem(key); + return; + } + // if a sensor is disabled, gray it out if (key in this._sensorMenuItems) { this._sensorMenuItems[key].setSensitive((value!='disabled')); diff --git a/sensors.js b/sensors.js index efdf2e0..9ecdc5b 100644 --- a/sensors.js +++ b/sensors.js @@ -48,6 +48,9 @@ export const Sensors = GObject.registerClass({ this.resetHistory(); + // interfaces seen by the last network query, to spot the ones that go away + this._network_interfaces = []; + this._last_processor = { 'core': {}, 'speed': [] }; this._settingChangedSignals = []; @@ -330,11 +333,45 @@ export const Sensors = GObject.registerClass({ } _queryNetwork(callback, dwell) { - for (let sensor of this._networkIfaces) { - new FileModule.File(sensor.path).read().then(value => { - this._returnValue(callback, sensor.name, value, sensor.type, 'storage'); - }).catch(err => { }); - } + // check network speed + let directions = ['tx', 'rx']; + let netbase = '/sys/class/net/'; + + new FileModule.File(netbase).list().then(interfaces => { + // 'lo' is always present, so an empty listing means the read failed + if (!interfaces.length) return; + + // issue #557 - forget interfaces the kernel no longer has + for (let iface of this._network_interfaces) { + if (interfaces.includes(iface)) continue; + + for (let direction of directions) { + if (iface == 'lo' && direction == 'rx') continue; + + let name = iface + ((iface == 'lo')?'':' ' + direction); + let type = 'network' + ((iface=='lo')?'':'-' + direction); + this._returnValue(callback, name, 'destroy', type, 'storage'); + } + } + + this._network_interfaces = interfaces; + + for (let iface of interfaces) { + for (let direction of directions) { + // lo tx and rx are the same + if (iface == 'lo' && direction == 'rx') continue; + + new FileModule.File(netbase + iface + '/statistics/' + direction + '_bytes').read().then(value => { + // issue #217 - don't include 'lo' traffic in Maximum calculations in values.js + // by not using network-rx or network-tx + let name = iface + ((iface == 'lo')?'':' ' + direction); + + let type = 'network' + ((iface=='lo')?'':'-' + direction); + this._returnValue(callback, name, value, type, 'storage'); + }).catch(err => { }); + } + } + }).catch(err => { }); if (this._hasWireless) this._queryWireless(callback); @@ -825,7 +862,7 @@ export const Sensors = GObject.registerClass({ } _returnValue(callback, label, value, type, format) { - if (value != 'disabled' && format !== 'string' && isNaN(value)) + if (value != 'disabled' && value != 'destroy' && format !== 'string' && isNaN(value)) return; callback(label, value, type, format); } diff --git a/values.js b/values.js index 4cd4b5f..c640108 100644 --- a/values.js +++ b/values.js @@ -416,6 +416,17 @@ export const Values = GObject.registerClass({ return output; } + // issue #557 - forget a removed interface, so its last counters stop being totalled + removeNetworkSensor(key, label, direction) { + for (let type of ['network', 'network-rx', 'network-tx']) + if (type in this._history) delete this._history[type][key]; + + delete this._networkSpeedOffset[key]; + + if (direction in this._networkSpeeds) + delete this._networkSpeeds[direction][label]; + } + resetHistory(numGpus) { // don't call this._history = {}, as we want to keep network-rx and network-tx // otherwise network history statistics will start over