Skip to content

Commit

Permalink
Merge branch 'master' into net48
Browse files Browse the repository at this point in the history
  • Loading branch information
josephmyers authored Jul 26, 2024
2 parents 459941c + e5745ec commit 9014eb8
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Added

- [SIL.Core] Added macOS support for `GlobalMutex`

## [14.1.1] - 2024-05-23

### Fixed
Expand Down
26 changes: 24 additions & 2 deletions SIL.Core/Threading/GlobalMutex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ namespace SIL.Threading
///
/// This is needed because Mono does not support system-wide, named mutexes. Mono does implement the Mutex class,
/// but even when using the constructors with names, it only works within a single process.
///
/// Note that in .NET 8.0 and later (and perhaps starting sooner than version 8), a named mutex can be used across
/// processes in Linux and macOS. However, software using the previous method of locking would not recognize the
/// new method of locking, so Linux continues to use the old, file-based approach internally.
/// </summary>
public class GlobalMutex : DisposableBase
{
Expand All @@ -24,14 +28,18 @@ public class GlobalMutex : DisposableBase

/// <summary>
/// Initializes a new instance of the <see cref="GlobalMutex"/> class.
/// A <see cref="GlobalMutex"/> object is only intended to work with other <see cref="GlobalMutex"/> objects.
/// The name provided may not be the exact name/ID used by the internal OS object(s) used to enforce the mutex.
/// </summary>
public GlobalMutex(string name)
{
_name = name;
if (!Platform.IsWindows)
if (Platform.IsWindows)
_adapter = new WindowsGlobalMutexAdapter(name);
else if (Platform.IsLinux)
_adapter = new LinuxGlobalMutexAdapter(name);
else
_adapter = new WindowsGlobalMutexAdapter(name);
_adapter = new ExplicitGlobalMutexAdapter(name);
}

/// <summary>
Expand Down Expand Up @@ -285,5 +293,19 @@ protected override void DisposeManagedResources()
_mutex.Dispose();
}
}

/// <summary>
/// A .NET native Mutex object works cross-process on all OSes if we prepend its name with "Global\".
/// On multi-user systems (e.g., Terminal Server on Windows) this can cause one user to grab the lock that another user
/// would like to get. If this is an important scenario, then a login session ID and/or username could be included in
/// the name of the Mutex. Without prepending "Global\", though, named Mutexes don't work cross-process on OSes other
/// than Windows.
/// </summary>
private class ExplicitGlobalMutexAdapter: WindowsGlobalMutexAdapter
{
private const string GLOBAL = "Global\\";

public ExplicitGlobalMutexAdapter(string name) : base(name.StartsWith(GLOBAL) ? name : $"{GLOBAL}{name}") {}
}
}
}
1 change: 1 addition & 0 deletions SIL.DictionaryServices/SIL.DictionaryServices.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<RootNamespace>SIL.DictionaryServices</RootNamespace>
<AssemblyTitle>SIL.DictionaryServices</AssemblyTitle>
<Description>SIL.DictionaryServices contains classes for defining a simple lexical model that can be used across applications.</Description>
<TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
Expand Down

0 comments on commit 9014eb8

Please sign in to comment.