<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Recent changes to Single Instance Mutexes</title><link>https://sourceforge.net/p/sucrose/wiki/Single%2520Instance%2520Mutexes/</link><description>Recent changes to Single Instance Mutexes</description><atom:link href="https://sourceforge.net/p/sucrose/wiki/Single%20Instance%20Mutexes/feed" rel="self"/><language>en</language><lastBuildDate>Sat, 04 Jul 2026 04:15:49 -0000</lastBuildDate><atom:link href="https://sourceforge.net/p/sucrose/wiki/Single%20Instance%20Mutexes/feed" rel="self" type="application/rss+xml"/><item><title>Single Instance Mutexes modified by Bayram Emekli</title><link>https://sourceforge.net/p/sucrose/wiki/Single%2520Instance%2520Mutexes/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v2
+++ v3
@@ -46,7 +46,7 @@
 | Reportdog | `{Sucrose-Wallpaper-Engine-Reportdog}` |
 | Backgroundog | `{Sucrose-Wallpaper-Engine-Backgroundog}` |

-All seven live engines share the single `{Sucrose-Wallpaper-Engine-Live}` mutex concept — only one wallpaper render engine may be alive at a time.
+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

&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Bayram Emekli</dc:creator><pubDate>Sat, 04 Jul 2026 04:15:49 -0000</pubDate><guid>https://sourceforge.net238b0be6262d4c41fd10d94e7e7171e624db4baf</guid></item><item><title>Single Instance Mutexes modified by Bayram Emekli</title><link>https://sourceforge.net/p/sucrose/wiki/Single%2520Instance%2520Mutexes/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v1
+++ v2
@@ -30,11 +30,11 @@

 ## The `Instance.Single` alternative

-An alternate helper, `Instance.Single(name, application)`, defers to `Skylark.Wing.Utility.SingleInstance.IsAppMutexRunning`. `Instance.Basic` is the one used by the startup gates documented below.
+An alternate helper, `Instance.Single(name, application)`, returns `Skylark.Wing.Utility.SingleInstance.IsAppMutexRunning(name) &amp;amp;&amp;amp; WorkCount(application) &amp;lt;= 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 global and brace-wrapped, defined in `src/Library/Sucrose.Memory/Manage/Readonly/Mutex.cs`.
+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 |
 |---|---|
@@ -56,13 +56,14 @@
 |---|---|
 | **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 | Not the same way — single-instancing is handled via the shared `{Sucrose-Wallpaper-Engine-Live}` mutex inside the engine code |
+| Live engines | Yes — each engine calls `Instance.Basic(SMMRM.Live, SMMRA.&amp;lt;engine&amp;gt;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.

@@ -72,7 +73,7 @@


 - **Launcher** — redirects: it calls `SSLCI.Command()` (open the Portal via `✔Interface✖&amp;lt;portal&amp;gt;`) and then `Close()`s itself.
 - **Portal** — simply `Close()`s (no second window).
-- **Property / Backgroundog / Reportdog** — exit without starting a second copy.
+- **Property / Backgroundog / Reportdog / Update** — exit without starting a second copy (via `Close()`).

 ## Double-launch behavior

&amp;lt;/portal&amp;gt;&amp;lt;/engine&amp;gt;&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Bayram Emekli</dc:creator><pubDate>Sat, 04 Jul 2026 04:15:47 -0000</pubDate><guid>https://sourceforge.net994b455ba0e9f2df96c9d8472ef46baacad7f14f</guid></item><item><title>Single Instance Mutexes modified by Bayram Emekli</title><link>https://sourceforge.net/p/sucrose/wiki/Single%2520Instance%2520Mutexes/</link><description>&lt;div class="markdown_content"&gt;&lt;h1 id="h-single-instance-mutexes"&gt;Single-Instance Mutexes&lt;/h1&gt;
&lt;p&gt;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, &lt;code&gt;Instance.Basic&lt;/code&gt;, that requires &lt;strong&gt;both&lt;/strong&gt; a freshly-created mutex &lt;strong&gt;and&lt;/strong&gt; 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.&lt;/p&gt;
&lt;h2 id="h-contents"&gt;Contents&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#the-instancebasic-rule"&gt;The &lt;code&gt;Instance.Basic&lt;/code&gt; rule&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#the-instancesingle-alternative"&gt;The &lt;code&gt;Instance.Single&lt;/code&gt; alternative&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#mutex-names"&gt;Mutex names&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#which-processes-gate"&gt;Which processes gate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#what-happens-when-the-gate-fails"&gt;What happens when the gate fails&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#double-launch-behavior"&gt;Double-launch behavior&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#see-also"&gt;See also&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="h-the-instancebasic-rule"&gt;The &lt;code&gt;Instance.Basic&lt;/code&gt; rule&lt;/h2&gt;
&lt;p&gt;File: &lt;code&gt;src/Shared/Sucrose.Shared.Space/Helper/Instance.cs&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Instance.Basic(name, application)&lt;/code&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Creates a named &lt;code&gt;Mutex(true, name, out createdNew)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Returns &lt;code&gt;createdNew &amp;amp;&amp;amp; Processor.WorkCount(application) &amp;lt;= 1&lt;/code&gt; — i.e. the mutex must be &lt;strong&gt;newly created&lt;/strong&gt; AND at most &lt;strong&gt;one&lt;/strong&gt; process of that executable name may currently exist.&lt;/li&gt;
&lt;li&gt;The whole thing is wrapped in a &lt;strong&gt;3-attempt retry&lt;/strong&gt;; on persistent failure it returns &lt;code&gt;false&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is a deliberately strict &lt;strong&gt;double-check&lt;/strong&gt;: 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.&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;Instance&lt;/span&gt;.&lt;span class="nv"&gt;Basic&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;application&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;:
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;Mutex&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;true&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;out&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;createdNew&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;createdNew&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;WorkCount&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;application&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="h-the-instancesingle-alternative"&gt;The &lt;code&gt;Instance.Single&lt;/code&gt; alternative&lt;/h2&gt;
&lt;p&gt;An alternate helper, &lt;code&gt;Instance.Single(name, application)&lt;/code&gt;, defers to &lt;code&gt;Skylark.Wing.Utility.SingleInstance.IsAppMutexRunning&lt;/code&gt;. &lt;code&gt;Instance.Basic&lt;/code&gt; is the one used by the startup gates documented below.&lt;/p&gt;
&lt;h2 id="h-mutex-names"&gt;Mutex names&lt;/h2&gt;
&lt;p&gt;Mutex names are global and brace-wrapped, defined in &lt;code&gt;src/Library/Sucrose.Memory/Manage/Readonly/Mutex.cs&lt;/code&gt;.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Process&lt;/th&gt;
&lt;th&gt;Mutex name&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Live engine (shared by all 7 engines)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{Sucrose-Wallpaper-Engine-Live}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Portal&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{Sucrose-Wallpaper-Engine-Portal}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Update&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{Sucrose-Wallpaper-Engine-Update}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Property&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{Sucrose-Wallpaper-Engine-Property}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Launcher&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{Sucrose-Wallpaper-Engine-Launcher}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reportdog&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{Sucrose-Wallpaper-Engine-Reportdog}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backgroundog&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{Sucrose-Wallpaper-Engine-Backgroundog}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;All seven live engines share the single &lt;code&gt;{Sucrose-Wallpaper-Engine-Live}&lt;/code&gt; mutex concept — only one wallpaper render engine may be alive at a time.&lt;/p&gt;
&lt;h2 id="h-which-processes-gate"&gt;Which processes gate&lt;/h2&gt;
&lt;p&gt;Processes that gate on single-instance via &lt;code&gt;Instance.Basic&lt;/code&gt; in their &lt;code&gt;OnStartup&lt;/code&gt; / &lt;code&gt;Main&lt;/code&gt;:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Process&lt;/th&gt;
&lt;th&gt;Gates with &lt;code&gt;Instance.Basic&lt;/code&gt;?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Launcher&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Portal&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Property&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Backgroundog&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Reportdog&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Commandog&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;No&lt;/strong&gt; — intentionally re-runnable short-lived broker&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Watchdog&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;No&lt;/strong&gt; — intentionally re-runnable short-lived crash handler&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Undo&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;No&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Live engines&lt;/td&gt;
&lt;td&gt;Not the same way — single-instancing is handled via the shared &lt;code&gt;{Sucrose-Wallpaper-Engine-Live}&lt;/code&gt; mutex inside the engine code&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;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 &lt;strong&gt;not&lt;/strong&gt; describe them as resident services.&lt;/p&gt;
&lt;h2 id="h-what-happens-when-the-gate-fails"&gt;What happens when the gate fails&lt;/h2&gt;
&lt;p&gt;If &lt;code&gt;Instance.Basic&lt;/code&gt; returns &lt;code&gt;false&lt;/code&gt; (an instance already exists), the process does &lt;strong&gt;not&lt;/strong&gt; stay resident. Behavior differs by process:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Launcher&lt;/strong&gt; — redirects: it calls &lt;code&gt;SSLCI.Command()&lt;/code&gt; (open the Portal via &lt;code&gt;✔Interface✖&amp;lt;Portal&amp;gt;&lt;/code&gt;) and then &lt;code&gt;Close()&lt;/code&gt;s itself.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Portal&lt;/strong&gt; — simply &lt;code&gt;Close()&lt;/code&gt;s (no second window).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Property / Backgroundog / Reportdog&lt;/strong&gt; — exit without starting a second copy.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="h-double-launch-behavior"&gt;Double-launch behavior&lt;/h2&gt;
&lt;p&gt;The most user-visible consequence: &lt;strong&gt;double-launching the Launcher opens the settings window, it does not create a second tray icon.&lt;/strong&gt; 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.&lt;/p&gt;
&lt;h2 id="h-see-also"&gt;See also&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="./Architecture-Overview"&gt;Architecture Overview&lt;/a&gt; — the full process roster.&lt;/li&gt;
&lt;li&gt;&lt;a href="/p/sucrose/wiki/Lifecycle/"&gt;Lifecycle&lt;/a&gt; — where the gate runs during cold start.&lt;/li&gt;
&lt;li&gt;&lt;a href="./Commandog-Dispatcher"&gt;Commandog Dispatcher&lt;/a&gt; — the re-runnable broker that does not gate.&lt;/li&gt;
&lt;li&gt;&lt;a href="./Data-Locations"&gt;Data Locations&lt;/a&gt; — exe and mutex names in context.&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Bayram Emekli</dc:creator><pubDate>Sat, 04 Jul 2026 04:15:37 -0000</pubDate><guid>https://sourceforge.net52eb3ce715991ee00b9d20e00f936a44c499bf28</guid></item></channel></rss>