Skip to content

Commit aa1525f

Browse files
committed
fix potential stuck install locks
1 parent 59ab8a7 commit aa1525f

File tree

1 file changed

+48
-31
lines changed

1 file changed

+48
-31
lines changed

src/extension.ts

Lines changed: 48 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -722,35 +722,38 @@ async function preStartup(context: vscode.ExtensionContext) {
722722

723723
let version = await findLatestServeD(firstTimeUser || force, channelString);
724724
async function doUpdate(): Promise<boolean> {
725-
let [isBlocked, lock] = await acquireInstallLock("serve-d", context);
726-
let retry = false;
727-
try {
728-
context.subscriptions.push(lock);
729-
let origUpdateFun = version ? (version.asset
730-
? installServeD([{ url: version.asset.browser_download_url, title: "Serve-D" }], version.name)
731-
: compileServeD((version && version.name != "nightly") ? version.name : undefined))
732-
: updateAndInstallServeD;
733-
let updateFun = origUpdateFun;
734-
if (isBlocked) {
735-
updateFun = function(env: NodeJS.ProcessEnv): Promise<boolean | undefined | "retry"> {
736-
return waitForOtherInstanceInstall("serve-d", context, force)
725+
let origUpdateFun = version ? (version.asset
726+
? installServeD([{ url: version.asset.browser_download_url, title: "Serve-D" }], version.name)
727+
: compileServeD((version && version.name != "nightly") ? version.name : undefined))
728+
: updateAndInstallServeD;
729+
let updateFun = origUpdateFun;
730+
731+
updateFun = async function(env: NodeJS.ProcessEnv): Promise<boolean | undefined | "retry"> {
732+
let [isBlocked, lock] = await acquireInstallLock("serve-d", context);
733+
try {
734+
context.subscriptions.push(lock);
735+
if (isBlocked) {
736+
return await waitForOtherInstanceInstall("serve-d", context, force)
737737
.then((doUpdate) => doUpdate ? origUpdateFun(env) : "retry");
738-
};
738+
}
739+
return await origUpdateFun(env);
739740
}
740-
let upToDate = await checkProgram(force, "servedPath", "serve-d", "serve-d",
741-
updateFun,
742-
version ? (version.asset ? "Download" : "Compile") : "Install", isServedOutdated(version));
743-
if (upToDate === undefined)
744-
return false; /* user dismissed install dialogs, don't continue startup */
745-
else if (upToDate === "retry")
746-
retry = true;
747-
} finally {
748-
let i = context.subscriptions.indexOf(lock);
749-
context.subscriptions.splice(i, 1);
750-
lock.dispose();
751-
}
741+
finally {
742+
let i = context.subscriptions.indexOf(lock);
743+
context.subscriptions.splice(i, 1);
744+
lock.dispose();
745+
}
746+
};
747+
748+
let upToDate = await checkProgram(force, "servedPath", "serve-d", "serve-d",
749+
updateFun,
750+
version ? (version.asset ? "Download" : "Compile") : "Install", isServedOutdated(version));
751+
if (upToDate === undefined)
752+
return false; /* user dismissed install dialogs, don't continue startup */
753+
else if (upToDate === "retry")
754+
return doUpdate();
752755

753-
return retry ? doUpdate() : true;
756+
return true;
754757
}
755758

756759
if (!await doUpdate())
@@ -773,18 +776,32 @@ async function preStartup(context: vscode.ExtensionContext) {
773776
}
774777
}
775778

779+
function lockIsStillAcquired(lock: any): boolean {
780+
return lock && isFinite(parseInt(lock)) && new Date().getTime() - parseInt(lock) < 10000;
781+
}
782+
776783
async function acquireInstallLock(depName: string, context: vscode.ExtensionContext): Promise<[boolean, vscode.Disposable]> {
777784
const installInProgress = "installInProgress-" + depName;
778-
var installing = context.globalState.get(installInProgress, undefined);
779-
context.globalState.update(installInProgress, true);
780-
return [!!installing, new vscode.Disposable(() => context.globalState.update(installInProgress, false))];
785+
let existingLock = context.globalState.get(installInProgress, undefined);
786+
if (lockIsStillAcquired(existingLock)) {
787+
return [false, new vscode.Disposable(() => {})];
788+
} else {
789+
context.globalState.update(installInProgress, new Date().getTime());
790+
let timer = setInterval(function() {
791+
context.globalState.update(installInProgress, new Date().getTime());
792+
}, 2000);
793+
return [true, new vscode.Disposable(() => {
794+
clearInterval(timer);
795+
context.globalState.update(installInProgress, false);
796+
})];
797+
}
781798
}
782799

783800
async function waitForOtherInstanceInstall(depName: string, context: vscode.ExtensionContext, forced: boolean, showProgress: boolean = true): Promise<boolean> {
784801
// XXX: horrible polling code here because there is no other IPC API for vscode extensions
785802
const installInProgress = "installInProgress-" + depName;
786-
var installing = context.globalState.get(installInProgress, undefined);
787-
if (installing) {
803+
var lock = context.globalState.get(installInProgress, undefined);
804+
if (lockIsStillAcquired(lock)) {
788805
if (forced) {
789806
let ret = new Promise<boolean>((resolve) => {
790807
setTimeout(function() {

0 commit comments

Comments
 (0)