Skip to content

同じ利用者が複数の Windows 対話セッションで動かした場合の共有資源の扱い (残: 多重起動の抑止と設定の保存) #52

Description

@limit7412

何が起きるか

同じ Windows ユーザーが、ユーザーの切り替えやリモートデスクトップで 2 つの対話セッションを持ち、同じインストール先の App を両方で動かした場合、プロセスは 2 つ走る一方、触る資源は共有される。

  • 多重起動の抑止 (App.SingleInstanceMutexName) は接頭辞の無い名前なので、セッションごとの名前空間に作られる。両セッションで別々に起動できる
  • 設定の保存 (SettingsStore.CrossProcessMutexName) も同じく接頭辞が無い。互いの保存を直列化できない
  • 更新の取得 (%AppData%\VRCToolsDataSync\update\<インストール先のハッシュ>\incoming.zip) は同じファイルを指す。取得の直列化 (UpdateManager._downloadGate) はプロセス内にしか効かない → PR fix(update): 取得をクロスプロセスで直列化し、入っている版と突き合わせる #74 で対応

更新機構の側は対応済み (PR #74)

案 1〜3 のどれとも少し違い、更新機構の中だけで閉じる 2 つを入れた。多重起動の抑止と設定の保存には触っていないので、下の「残っていること」はそのまま残る。

  • 取得の直列化を Global\ にした (UpdateStage.CreateDownloadMutex)。書き始めから昇格または破棄までと、後始末を押さえる。適用のロックとは別に置き、取る順は「取得 → 適用」で揃えた。取れないときは見送らずに待つ (要求は _pending から取り出した後なので、落とすと次の確認まで誰も取りに行かない)
  • 適用の直前に、インストール先に入っている版と突き合わせるようにした (UpdateInstaller.InstalledAppVersion)。TryLoadVerified の版の前後の判定は実行中のプロセスの版だけを見ており、適用のロックを待っていた旧版の App が素通りして 2 度目の置き換えへ進めた。これが .old を失う筋だった

これで、本文にある「完成済みのファイルを消す」と、8/30 のコメントにある「.old が上書きされて本当の旧版が失われる」が両方閉じた。

残っていること

1. 多重起動の抑止と設定の保存の名前空間

ここがこの issue の本体である。名前空間をどう揃えるかは機能をまたぐ判断になる。

  • 抑止を Global\ にすると、2 つ目のセッションでは「既に起動しています」と言われて何も出てこない (先行インスタンスは別セッションにあり、ウィンドウを見せられない)。利用者から見ると壊れている
  • セッションごとに動かせるままにするなら、設定ファイルの側をセッション間で直列化するか、セッションごとに分ける必要がある

案。

  1. 共有資源に触る所を Global\ の名前で直列化する
  2. 設定の置き場所をセッションごとに分ける。ディスクは食うが、互いに干渉しない
  3. 2 つ目のセッションでは一部の機能を降りる

2. 置き換えの最中に、別セッションの App が旧 app\ を掴む

8/30 のコメントに書いた 2 つの影響のうち、後半 (.old の上書き) は PR #74 で閉じた。前半は残っている。

別セッションの App は接頭辞の無い抑止を素通りして起動し、旧 app\ の DLL を読み込む。掴まれたままだと、ヘルパの入れ替え (リネーム) が失敗する。

ただし UpdateInstaller が巻き戻し、取得は残るので、次の機会に適用し直される。壊れる方向の失敗ではない。抑止を Global\ にすれば消えるので、1 とセットで決まる。

3. UpdateStage.Discard()incoming.zip も消す

Discard() は適用のロックの下からしか呼ばれず、取得のロックは取らない。別セッションが取得している最中に「再起動して適用」を押されると、書きかけを消しうる。

塞ぐには「どのファイルをどちらのロックが持つか」を組み替えることになり、#48 の中断からの復旧の判定 (横に残った記録を ZIP と突き合わせて仕上げる経路) に触れる。失うのは取得のやり直し 1 回で、.old や設定を失う類ではないため、PR #74 では触らずに記録だけ残した。

前提

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions