Compare commits

...

1 Commits

Author SHA1 Message Date
wheaney 5da8d05ebf Fix async request handling 2024-07-24 11:00:01 -07:00
1 changed files with 39 additions and 19 deletions

View File

@ -87,7 +87,7 @@ function getMonitorConfig(displayConfigProxy, callback) {
// triggers callback with true result if an an async monitor config change was triggered, false if no config change needed // triggers callback with true result if an an async monitor config change was triggered, false if no config change needed
function performOptimalModeCheck(displayConfigProxy, connectorName, headsetAsPrimary, useHighestRefreshRate, function performOptimalModeCheck(displayConfigProxy, connectorName, headsetAsPrimary, useHighestRefreshRate,
allowConfigUpdateFn, callback) { callback, allowConfigUpdateFn) {
Globals.logger.log_debug(`monitormanager.js performOptimalModeCheck for ${connectorName}`); Globals.logger.log_debug(`monitormanager.js performOptimalModeCheck for ${connectorName}`);
displayConfigProxy.GetCurrentStateRemote((result, error) => { displayConfigProxy.GetCurrentStateRemote((result, error) => {
@ -248,10 +248,11 @@ export const MonitorManager = GObject.registerClass({
this._backendManager = null; this._backendManager = null;
this._monitorProperties = null; this._monitorProperties = null;
this._changeHookFn = null; this._changeHookFn = null;
this._needsConfigCheck = this.use_optimal_monitor_config;
// help prevent certain actions from taking place multiple times in the event of rapid monitor updates // help prevent certain actions from taking place multiple times in the event of rapid monitor updates
this._configCheckRequestCount = this.use_optimal_monitor_config ? 1 : 0; this._asyncRequestsInFlight = 0;
this._asyncRequestsCount = 0; this._configCheckRequestsCount = 0;
} }
enable() { enable() {
@ -299,19 +300,33 @@ export const MonitorManager = GObject.registerClass({
return false; return false;
} }
let needsConfigCheck = this._configCheckRequestCount > 0; const isCheckingConfig = this._needsConfigCheck;
if (needsConfigCheck && --this._configCheckRequestCount === 0) { if (this._needsConfigCheck && this._asyncRequestsInFlight === 0) {
this._asyncRequestsCount++; this._asyncRequestsInFlight++;
const allowConfigUpdateFn = (() => this._asyncRequestsCount === 1).bind(this);
const configCheckCountSnapshot = this._configCheckRequestsCount;
const allowConfigUpdateFn = (() => {
// allow updates to the config if this is the only in-flight request and no more requests
// were made while we were waiting for the previous request to complete
return this._asyncRequestsInFlight === 1 && this._configCheckRequestsCount === configCheckCountSnapshot;
}).bind(this);
performOptimalModeCheck(this._displayConfigProxy, monitorConnector, this.headset_as_primary, this.use_highest_refresh_rate, ((configChanged, error) => { performOptimalModeCheck(this._displayConfigProxy, monitorConnector, this.headset_as_primary, this.use_highest_refresh_rate, ((configChanged, error) => {
if (--this._asyncRequestsCount > 0) { if (--this._asyncRequestsInFlight > 0) {
Globals.logger.log_debug(`MonitorManager _on_monitors_change: ${this._asyncRequestsCount} async requests still pending, skipping change hook`); Globals.logger.log_debug(`MonitorManager needsOptimalModeCheck: ${this._asyncRequestsInFlight} async requests still pending, skipping change hook`);
return;
} else if (this._configCheckRequestsCount !== configCheckCountSnapshot) {
Globals.logger.log_debug('MonitorManager needsOptimalModeCheck: config checks requested while in-flight, skipping change hook');
return; return;
} }
if (error) { if (error) {
Globals.logger.log(`Failed to switch to optimal mode for monitor ${monitorConnector}: ${error}`); Globals.logger.log(`Failed to switch to optimal mode for monitor ${monitorConnector}: ${error}`);
// tell the extension to proceed, this should result in another config check
this._changeHookFn();
} else { } else {
this._needsConfigCheck = false;
if (configChanged) { if (configChanged) {
Globals.logger.log(`Switched to optimal mode for monitor ${monitorConnector}`); Globals.logger.log(`Switched to optimal mode for monitor ${monitorConnector}`);
} else if (!!this._changeHookFn) { } else if (!!this._changeHookFn) {
@ -324,10 +339,12 @@ export const MonitorManager = GObject.registerClass({
} }
} }
}).bind(this), this._allowConfigChange.bind(this)); }).bind(this), this._allowConfigChange.bind(this));
} else { } else if (!this._needsConfigCheck) {
Globals.logger.log_debug('MonitorManager needsOptimalModeCheck: skipping config check'); Globals.logger.log_debug('MonitorManager needsOptimalModeCheck: skipping config check');
} else {
Globals.logger.log_debug(`MonitorManager needsOptimalModeCheck: skipping due to async requests ${this._asyncRequestsInFlight}`);
} }
return needsConfigCheck; return isCheckingConfig;
} }
_on_monitors_change() { _on_monitors_change() {
@ -335,18 +352,17 @@ export const MonitorManager = GObject.registerClass({
if (this._displayConfigProxy == null) { if (this._displayConfigProxy == null) {
return; return;
} }
if (this.use_optimal_monitor_config) this._configCheckRequestCount++; if (this.use_optimal_monitor_config) {
this._asyncRequestsCount++; this._needsConfigCheck = true;
getMonitorConfig(this._displayConfigProxy, ((result, error) => { this._configCheckRequestsCount++;
if (--this._asyncRequestsCount > 0) {
Globals.logger.log_debug(`MonitorManager _on_monitors_change: ${this._asyncRequestsCount} async requests still pending, skipping change hook`);
return;
} }
this._asyncRequestsInFlight++;
getMonitorConfig(this._displayConfigProxy, ((result, error) => {
if (error) { if (error) {
Globals.logger.log(error); Globals.logger.log(error);
return; return;
} }
const monitorProperties = []; const monitorProperties = [];
for (let i = 0; i < result.length; i++) { for (let i = 0; i < result.length; i++) {
const [monitorName, connectorName, vendor, product, serial, refreshRate] = result[i]; const [monitorName, connectorName, vendor, product, serial, refreshRate] = result[i];
@ -366,7 +382,11 @@ export const MonitorManager = GObject.registerClass({
} }
this._monitorProperties = monitorProperties; this._monitorProperties = monitorProperties;
if (!!this._changeHookFn) { if (!!this._changeHookFn) {
if (--this._asyncRequestsInFlight === 0) {
this._changeHookFn(); this._changeHookFn();
} else {
Globals.logger.log_debug(`MonitorManager _on_monitors_change: ${this._asyncRequestsInFlight} requests still pending, skipping change hook`);
}
} else { } else {
Globals.logger.log('MonitorManager _on_monitors_change: can\'t trigger change hook, no hook set!'); Globals.logger.log('MonitorManager _on_monitors_change: can\'t trigger change hook, no hook set!');
} }