Skip to content

Single Instance Mutexes

Taiizor edited this page Jun 19, 2026 · 3 revisions

Single-Instance Mutexes

Several Sucrose processes must run as a single instance — you should never have two tray icons, two settings windows, or two background services fighting over the same state. Sucrose enforces this with named Windows mutexes through a deliberately strict gate, Instance.Basic, that requires both a freshly-created mutex and a process-count check. This page documents the gate, the full mutex-name table, which processes gate versus which are intentionally re-runnable, and what happens on a double launch.

Contents

The Instance.Basic rule

File: src/Shared/Sucrose.Shared.Space/Helper/Instance.cs.

Instance.Basic(name, application):

  1. Creates a named Mutex(true, name, out createdNew).
  2. Returns createdNew && Processor.WorkCount(application) <= 1 — i.e. the mutex must be newly created AND at most one process of that executable name may currently exist.
  3. The whole thing is wrapped in a 3-attempt retry; on persistent failure it returns false.

This is a deliberately strict double-check: a fresh mutex alone is not enough — the process-count safeguard catches edge cases where a mutex was abandoned but a copy of the process is still alive.

Instance.Basic(name, application):
    Mutex(true, name, out createdNew)
    return createdNew && WorkCount(application) <= 1

The Instance.Single alternative

An alternate helper, Instance.Single(name, application), returns Skylark.Wing.Utility.SingleInstance.IsAppMutexRunning(name) && WorkCount(application) <= 1 — i.e. it pairs the Skylark.Wing mutex check with the same process-count safeguard used by Instance.Basic. Instance.Basic is the one used by the startup gates documented below.

Mutex names

Mutex names are well-known, brace-wrapped constants (session-local — no Global\ prefix, so each is created in the per-session namespace), defined in src/Library/Sucrose.Memory/Manage/Readonly/Mutex.cs.

Process Mutex name
Live engine (shared by all 7 engines) {Sucrose-Wallpaper-Engine-Live}
Portal {Sucrose-Wallpaper-Engine-Portal}
Update {Sucrose-Wallpaper-Engine-Update}
Property {Sucrose-Wallpaper-Engine-Property}
Launcher {Sucrose-Wallpaper-Engine-Launcher}
Reportdog {Sucrose-Wallpaper-Engine-Reportdog}
Backgroundog {Sucrose-Wallpaper-Engine-Backgroundog}

All eight live engines share the single {Sucrose-Wallpaper-Engine-Live} mutex concept — only one wallpaper render engine may be alive at a time.

Which processes gate

Processes that gate on single-instance via Instance.Basic in their OnStartup / Main:

Process Gates with Instance.Basic?
Launcher Yes
Portal Yes
Update Yes
Property Yes
Backgroundog Yes
Reportdog Yes
Commandog No — intentionally re-runnable short-lived broker
Watchdog No — intentionally re-runnable short-lived crash handler
Undo No
Live engines Yes — each engine calls Instance.Basic(SMMRM.Live, SMMRA.<engine>Live) (the shared {Sucrose-Wallpaper-Engine-Live} mutex) ANDed with an extra SSEHR.Check() engine-readiness check, so only one render engine may be alive at a time

Commandog and Watchdog must be re-runnable: many actions and many crashes can occur in quick succession, and each spawns a fresh short-lived broker/handler. Do not describe them as resident services.

What happens when the gate fails

If Instance.Basic returns false (an instance already exists), the process does not stay resident. Behavior differs by process:

  • Launcher — redirects: it calls SSLCI.Command() (open the Portal via ✔Interface✖<Portal>) and then Close()s itself.
  • Portal — simply Close()s (no second window).
  • Property / Backgroundog / Reportdog / Update — exit without starting a second copy (via Close()).

Double-launch behavior

The most user-visible consequence: double-launching the Launcher opens the settings window, it does not create a second tray icon. Because the second Launcher instance fails the gate and redirects through Commandog to open the Portal, the user gets the management UI rather than a duplicate tray presence. Likewise, asking to open the Portal while it is already running just focuses on the existing window instead of spawning a duplicate.

See also

Home

Getting Started

Wallpaper Types

Using Sucrose

Settings Reference

Creating Wallpapers

Engine Reference

Automation & Command Line

Architecture & Internals

Data, Files & Diagnostics

Building & Contributing

Help & Support

Clone this wiki locally