With the upcoming MBS Xojo Plugins 26.3 release, we introduce a new helper class: AutoMutexMBS. This class makes working with mutexes safer and more convenient by automatically releasing locks when an object goes out of scope.
The Problem with Manual Unlocking
When working with MutexMBS, it is important to always pair every Lock call with a corresponding Unlock call:
Var m As New MutexMBS
m.Lock
// Protected code here
m.Unlock
This works well as long as execution reaches the Unlock statement. However, if an exception occurs or a method exits unexpectedly, the unlock call may never happen. The mutex remains locked and other threads may block indefinitely.
Introducing AutoMutexMBS
The new AutoMutexMBS class follows the RAII (Resource Acquisition Is Initialization) pattern commonly used in C++. The object acquires the lock when it is created and automatically releases it in its destructor when the object is destroyed.
To support this pattern, MutexMBS now provides two convenience methods:
-
AutoLock As AutoMutexMBS -
TryAutoLock As AutoMutexMBS
Using AutoLock
Instead of manually calling Lock and Unlock, create a local AutoMutexMBS variable:
Public Sub UpdateData(m As MutexMBS)
Var lock As AutoMutexMBS = m.AutoLock
// Protected code here
End Sub
When the method ends, the local variable goes out of scope. The AutoMutexMBS destructor automatically unlocks the mutex. No explicit Unlock call is required.
Important: Store the Result in a Local Variable
The most important rule is to keep the returned AutoMutexMBS object in a local variable. The lifetime of the lock is tied directly to the lifetime of that object.
This is the correct way to use it:
Var lock As AutoMutexMBS = m.AutoLock
// Protected code
and this may not work as expected:
call m.AutoLock
// Protected code
In the second example, the returned object is not stored anywhere and is destroyed immediately, causing the mutex to be released sooner than expected. Always keep the returned object in a variable for as long as the lock should remain active.
Using TryAutoLock
If you want to attempt a lock without blocking, use TryAutoLock:
Var lock As AutoMutexMBS = m.TryAutoLock
If lock = Nil Then
// Could not obtain lock
Return
End If
// Protected code
The returned object is Nil if the mutex could not be locked. Otherwise, it behaves exactly like an object returned from AutoLock.
Exception Safety
One of the biggest advantages of AutoMutexMBS is exception safety. Consider this code:
m.Lock
DoSomething
m.Unlock
If DoSomething raises an exception, the unlock call may never execute. Using AutoMutexMBS avoids this problem:
Var lock As AutoMutexMBS = m.AutoLock
DoSomething
Even if an exception occurs, the local variable will be cleaned up as the stack unwinds, and the mutex will be released automatically.
Available in MBS Plugins 26.3
The new AutoMutexMBS class is available in MBS Xojo Plugins 26.3 and works on macOS, Windows, Linux, and iOS. It provides a safer and cleaner way to manage mutexes and helps prevent common bugs caused by forgotten unlock calls.
Whenever possible, prefer AutoLock and TryAutoLock over manual Lock/Unlock pairs.