Results 1 to 16 of 16

Thread: CMutexEx Class for Safer & Cooperative Mutex Handling

Threaded View

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,897

    CMutexEx Class for Safer & Cooperative Mutex Handling

    CMutexEx — A Safe, Cooperative, Cancellable Win32 Mutex Wrapper for VB6 - cross-process coordination made simple

    CMutexEx is a small, production-ready class that wraps Windows named mutexes with a clean VB6/twinBASIC API: blocking or cancellable waits, timeouts, short-circuit detection, abandoned owner detection, and optional SDDL-based security. Namespaces map to the real Win32 object namespaces: Global (system-wide) and Local (session-scoped).

    Why this class?
    Win32 mutex APIs are powerful but tricky (namespaces, UI pumping, abandoned states, security). CMutexEx gives you a small, well-documented surface that “does the right thing” by default—and still lets you opt into advanced features when you need them.

    Highlights
    • Namespaces: Global (machine-wide) or Local (current logon session)
    • Wait modes: blocking (classic) or cancellable (UI stays responsive via message pump)
    • Timeouts: INFINITE, finite ms, or zero-wait (“try once”)
    • Short-circuits: abort acquisition if any named mutex from a list exists (e.g., “Shutdown”)
    • Abandoned detection: signals when prior owner crashed (WAIT_ABANDONED_0)
    • Security (optional): pass SDDL to build a DACL (e.g., allow all users to synchronize only)
    • Events: Acquiring(ByRef Cancel As Boolean), Acquired(IsAbandoned As Boolean), Failed(IsExpected As Boolean)
    • Performance: ~70k acquire/release cycles/sec compiled (fast path)


    When to use System/Global vs Session/Local Mutexes
    • Global\ (System Mutex): coordinate across all users/processes on the machine (installers, shared files, single-instance app across users).
    • Local\ (Session Mutex): coordinate inside the current logon session (per-user single-instance, per-session helpers).


    Mutex Factory Helpers You'll Use
    • Critical: infinite, blocking — database writes, installers, migrations
    • Reactive: infinite, cancellable — user-initiated tasks that should politely yield
    • ZeroWait: instant decision — single-instance, opportunistic background tasks
    • Timed: finite wait — retry loops, background syncs that should skip when busy
    • Perpetual: Zero-wait, acquired permanently for the app process lifetime.


    ? Quick Start

    Blocking, infinite wait with short-circuit (critical section):
    Code:
    Sub Main()
       If DbMigrationNeeded Then
          With NewCriticalSystemMutex("Database_Migration", "Database_Migration_Complete")   ' Get Database Migration mutex or short-circuit if another process performs the migration
             If .IsShortCircuited Then 
                 ' Database migration completed successfully by another process, continue as normal
    
             ElseIf .IsAcquired Then
                ' Mutex acquired - perform database migration
    
                MigrateDatabase
    
             Else
                ' Something else happened! Should abort!!
                Err.Raise vbObjectError, , "Migration error!"
             End If
          End With ' auto-release mutex
       End If
    End Sub
    
    Private Sub MigrateDatabase()
       ' DoDatabaseMigrationWorkHere 
    
       If NewPerpetualSystemMutex("Database_Migration_Completed") Then   ' Perpetual mutexes will NEVER be released until app process terminates
          ' Migration Completed OK and we acquired a perpetual mutex to signal that no further migrations should be attempted
    
       Else
          ' Uhoh! Could not acquire mutex!!
          Err.Raise vbObjectError,  , "Could not acquire migration complete mutex!!
       End If
    End Sub
    Cancellable wait (responsive UI):
    Code:
    Private WithEvents m As CMutexEx
    
    Private Sub StartWork()
    Set m = NewReactiveSystemMutex("Report_Generation")
    If m.IsAcquired Then RunReport
    End Sub
    
    Private Sub m_Acquiring(Cancel As Boolean)
    If UserPressedCancel Then Cancel = True
    End Sub
    Zero-wait “try once” (single-instance guard):
    Code:
    Private Sub Form_Load()
       With NewZeroWaitSessionMutex("App_Main")
          If Not .IsAcquired Then
             MsgBox "Already running!", vbExclamation
          
             Unload Me
          End If
       End With
    End Sub
    Short-circuit if “Shutdown” mutex exists:
    Code:
    With NewCriticalSystemIndex("Reindex", Array("Global\Shutdown"))
        If .IsShortCircuited Then Exit Sub
        If .IsAcquired Then DoReindex
    End With
    API Overview
    • Prepare(Name, [Namespace], [ShortCircuits], [SDDL], [ErrorPolicy])
    • Acquire([TimeoutMs], [WaitBehavior], [ErrorPolicy])
    • PrepareAndAcquire(Name, [Timeout], [Behavior], [Namespace], [ShortCircuits], [SDDL], [ErrorPolicy])
    • Release
      — drop ownership but keep handle prepared for re-acquire
    • Cancel
      — cooperative cancel during cancellable waits
    • State helpers: IsAcquired, IsTimedOut, IsCancelled, IsShortCircuited, IsFailed, IsAbandoned


    Other Notes
    • Mutex names are case-sensitive.
    • In cancellable mode, the class uses MsgWaitForMultipleObjects to keep the UI responsive.
    • On any non-success path, resources are cleaned and state is set consistently.
    • You can attach a list of “short-circuit” names to abort acquisition if those mutexes show up.


    Feedback and bug reports are very welcome!

    Changelog
    • v1.0 — Initial public release. Single-use lifecycle, cancellable waits, short-circuits, abandoned detection, bitmask error policy, Global/Local helpers, SDDL support.
    • v1.01 — Fixed a bug in short-circuiting logic (using wrong Mutex Name variable).
    • v1.02 — Fixed a bug with too early LocalFree call - would obfuscate Err.LastDllError result of CreateMutex call and erroneous report error creating mutex instead of waiting for acquire.
    • v1.03 — Improvements to the demo app to prevent re-entrancy in Cancellable mode. Also add improved comments and messages to the demo.
    • v2.0 — Major refactor with lots of changes to the available methods, and new CMutexEx factory with helpers for common use cases, improvements to the demo, and some bug fixes.
    Attached Files Attached Files
    Last edited by jpbro; Oct 27th, 2025 at 03:42 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width