Skip to content
Snippets Groups Projects
Commit 435beae0 authored by Reiter, Christoph's avatar Reiter, Christoph :snake:
Browse files

Use async-mutex to avoid start/stop being racy

With both being async it's hard to follow what would happen if both run at the same
time, so just prevent it and serialize start/stopping instead.
parent d0ed480f
No related branches found
No related tags found
No related merge requests found
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
}, },
"dependencies": { "dependencies": {
"@open-wc/scoped-elements": "^1.1.1", "@open-wc/scoped-elements": "^1.1.1",
"async-mutex": "^0.2.4",
"dbp-common": "^1.0.0", "dbp-common": "^1.0.0",
"jsqr": "^1.3.1", "jsqr": "^1.3.1",
"lit-element": "^2.3.1", "lit-element": "^2.3.1",
......
...@@ -7,6 +7,7 @@ import {Icon, MiniSpinner} from 'dbp-common'; ...@@ -7,6 +7,7 @@ import {Icon, MiniSpinner} from 'dbp-common';
import {classMap} from 'lit-html/directives/class-map.js'; import {classMap} from 'lit-html/directives/class-map.js';
import jsQR from "jsqr"; import jsQR from "jsqr";
import {getIconSVGURL} from 'dbp-common'; import {getIconSVGURL} from 'dbp-common';
import {Mutex} from 'async-mutex';
/** /**
...@@ -118,6 +119,7 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { ...@@ -118,6 +119,7 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) {
this._videoElement = null; this._videoElement = null;
this._outputData = null; this._outputData = null;
this._videoRunning = false; this._videoRunning = false;
this._lock = new Mutex();
} }
static get scopedElements() { static get scopedElements() {
...@@ -143,23 +145,21 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { ...@@ -143,23 +145,21 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) {
}; };
} }
connectedCallback() { async connectedCallback() {
super.connectedCallback(); super.connectedCallback();
i18n.changeLanguage(this.lang); i18n.changeLanguage(this.lang);
this.updateComplete.then(async ()=>{ let devices = await getVideoDevices();
let devices = await getVideoDevices(); this._activeCamera = getPrimaryDevice(devices) || '';
this._activeCamera = getPrimaryDevice(devices) || ''; this._devices = devices;
this._devices = devices;
if (!this.stopScan) { if (!this.stopScan) {
this.startScanning(); await this.startScanning();
} }
});
} }
disconnectedCallback() { async disconnectedCallback() {
this.stopScanning(); await this.stopScanning();
super.disconnectedCallback(); super.disconnectedCallback();
} }
...@@ -187,9 +187,19 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { ...@@ -187,9 +187,19 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) {
* Init and start the video and QR code scan * Init and start the video and QR code scan
*/ */
async startScanning() { async startScanning() {
this.stopScanning(); await this.stopScanning();
this.stopScan = false; const release = await this._lock.acquire();
try {
await this._startScanning();
} finally {
release();
}
}
async _startScanning() {
console.assert(this._lock.isLocked());
await this.updateComplete;
let canvasElement = this._("#canvas"); let canvasElement = this._("#canvas");
let firstDrawDone = false; let firstDrawDone = false;
...@@ -322,24 +332,29 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { ...@@ -322,24 +332,29 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) {
* *
*/ */
async stopScanning() { async stopScanning() {
if (this._videoElement !== null) { const release = await this._lock.acquire();
let video = this._videoElement; try {
video.srcObject.getTracks().forEach(function(track) { if (this._videoElement !== null) {
track.stop(); let video = this._videoElement;
}); video.srcObject.getTracks().forEach(function(track) {
this._videoElement = null; track.stop();
} });
this._videoElement = null;
}
if (this._requestID !== null) { if (this._requestID !== null) {
cancelAnimationFrame(this._requestID); cancelAnimationFrame(this._requestID);
this._requestID = null; this._requestID = null;
} }
this._askPermission = false; this._askPermission = false;
this._videoRunning = false; this._videoRunning = false;
this._loading = false; this._loading = false;
this._loadingMessage = ''; this._loadingMessage = '';
} finally {
release();
}
} }
static get styles() { static get styles() {
......
...@@ -1603,6 +1603,13 @@ async-limiter@~1.0.0: ...@@ -1603,6 +1603,13 @@ async-limiter@~1.0.0:
resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd"
integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==
async-mutex@^0.2.4:
version "0.2.4"
resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.2.4.tgz#f6ea5f9cc73147f395f86fa573a2af039fe63082"
integrity sha512-fcQKOXUKMQc57JlmjBCHtkKNrfGpHyR7vu18RfuLfeTAf4hK9PgOadPR5cDrBQ682zasrLUhJFe7EKAHJOduDg==
dependencies:
tslib "^2.0.0"
async@0.9.x: async@0.9.x:
version "0.9.2" version "0.9.2"
resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d"
...@@ -8459,6 +8466,11 @@ tslib@^1.9.3: ...@@ -8459,6 +8466,11 @@ tslib@^1.9.3:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
tslib@^2.0.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c"
integrity sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==
tunnel-agent@^0.6.0: tunnel-agent@^0.6.0:
version "0.6.0" version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment