Closed drieseng closed 4 years ago
Related to dotnet/runtime#4370
Duplicate of issue dotnet/runtime#4370.
I wouldn't say it's a duplicate. That issue was resolved by removing the functionality. It would be nice to actually fix the actual problem and restore the functionality.
I'm sure @migueldeicaza will be eager to port this from Mono to .NET Core :p
Miguel can correct me if I'm wrong, but I don't believe Mono implements this either, or more specifically I believe they implement it the same general manner that the coreclr did before it was disabled to throw those exceptions: the names are only process-wide, not cross-process. That's why we decided to throw exceptions on coreclr; otherwise, since names are typically used for cross-process synchronization, you use the names thinking you're getting cross-process synchronization, but in reality you've just got a bunch of race conditions silently waiting to cause problems.
Reopened because of @mikedn comment.
My search for ways to add a cross-process mutex didn't yield many options. I'm currently planning on this:
Currently, we are looking for the following features:
Any other ideas?
CC @kangaroo
cc @krytarowski for NetBSD
I don't have anything portable offhand, other than maybe <semaphore.h>
or pthread_mutexattr_init
(3).
Mono's create named semaphore implementation is situated at: https://github.com/mono/mono/blob/ef40790/mono/io-layer/semaphores.c#L193-L289.
Mono's create named semaphore
Mono's implementation is not cross-process.
I'm confused, what's the current state of named Mutexes in core? Will they work on windows and linux?
There was an implementation with POSIX robust mutexes on Linux.
so that's a yes? It'd be really nice if yes as I can get rid of the file locking hacks!
I guess so, this is why I need to implement POSIX robust mutexes on my platform (NetBSD).
I've just tried on Ubuntu 14.04 and the answer is a no
I've just tried on Ubuntu 14.04 and the answer is a no
What code did you try? Named mutexes should work fine on in Ubuntu.
Interesting, this is my code, other processes are not honouring the mutex and are acquiring the mutex and repeating the same work. It works in Windows as expected.
using (var m = new Mutex(false, mutexName))
{
var hasMutex = false;
try
{
if (m.WaitOne(2))
{
hasMutex = true;
ProcessIterationAsync(currentOutputFileNameBase, c, _config.CountryCode).Wait();
}
}
catch (AbandonedMutexException e)
{
continue;
}
catch (Exception e)
{
continue;
}
finally
{
if (hasMutex)
{
m.ReleaseMutex();
}
}
}
What name did you use? By default, names have session scope and sessions are more granular on Unix (each terminal gets its own session). If you haven't already, please try adding a "Global\" prefix to the name minus the quotes.
There is build-time code to detect if the system supports POSIX robust mutexes, see https://github.com/dotnet/coreclr/blob/master/src/pal/src/configure.cmake#L997 and https://github.com/dotnet/coreclr/blob/master/src/pal/src/configure.cmake#L1020. Based on that, it would use POSIX robust mutexes or file locks, but it should work either way.
Although unrelated, in the above code, when an AbandonedMutexException is thrown, the thread is still given ownership of the lock, so you'd have to ReleaseMutex on that path as well
I prefixed the name with "Global\"as suggested here to no avail. I am running the processes in multiple screen instances. This is with RC4 (installed with apt-get)
Would it be possible to provide a small runnable repro? I can give it a try and see what's going on.
I took this down to the most basic example I could make and it worked... so I worked backwards and fixed. It was the missing "Global\" along with a few other things - User error - thanks and sorry!
Ok great
Hi!
I have try the following program in Debian 9 and it seems mutex is not global (cross-process):
using System;
using System.Threading;
namespace test_mutex
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Started! Try to Mutex.ctor...");
var m = new Mutex(false, @"Global\aaaaa");
Console.WriteLine("We have the Mutex! Try to lock mutex...");
m.WaitOne();
Console.WriteLine("Locked! Sleep...");
for (int i = 5; i > 0; --i)
{
Console.WriteLine(" {0}", i);
Thread.Sleep(1000);
}
Console.WriteLine("Sleep done! Release mutex...");
m.ReleaseMutex();
Console.WriteLine("Done.");
m.Close();
}
}
}
I started two instances of the application and both of them counting down simultaneously.
Would you be so kind to clarify is it my mistake or Mono bug?
Would you be so kind to clarify is it my mistake or Mono bug?
Are you using .NET Core or Mono?
@stephentoub, I try Mono 5.18.0.240
and 6.1.0 (master/72512cfbcbc Thu Feb 21 19:00:53 MSK 2019)
.
Thanks. This issue / repo are for coreclr. Can you open an issue instead in http://github.com/mono/mono?
@stephentoub, Oh, I see. I chose wrong project. My apologies!
No worries; it's confusing :)
Sorry for pinging on old thread. What is the situation for Semaphore
? Which seems to still only support named instance on Windows.
Which seems to still only support named instance on Windows.
Correct.
Would you be so kind to clarify is it my mistake or Mono bug?
Are you using .NET Core or Mono?
@stephentoub is there documentation about how global mutex works on each platform supported by net core? I’m trying to get a better understanding of the implementation for Linux, OS X and Win any pointers in the right direction would be appreciated (netcore 3.1)
is there documentation about how global mutex works on each platform supported by net core? I’m trying to get a better understanding of the implementation for Linux, OS X and Win any pointers in the right direction would be appreciated (netcore 3.1)
Documentation about the implementation? I don't know if @kouvel published a design doc anywhere for the Unix implementations; he might be able to point you to something. Your best bet though is probably just the implementation source code.
Your best bet though is probably just the implementation source code.
Any way you can point me to it? The code base is extensive and so far I've had no luck with it.
The closest summary is probably from the original PR: https://github.com/dotnet/coreclr/pull/5030. I thought they were in the code somewhere but apparently not, I have filed an issue to get those into code.
Most of the relevant code is here:
Roughly, they should behave the same way as on Windows. There may be some corner cases where they behave slightly differently, for example when the last handle to a mutex object is closed while the lock is held by a different thread.
On Windows the native objects are used (CreateMutex, etc.), on Linuxes where pthread robust mutexes are supported, they are used, and on OSX file locks are used.
Creating a named mutex on Unix currently throws a PlatformNotSupportedException stating "Named synchronization primitives are not supported on this platform".
Is this scheduled to arrive ? I'm sure @migueldeicaza will be eager to port this from Mono to .NET Core :p
Personally, I don't think it makes sense to expose APIs on both Windows and Unix, but only implement them on one of them. In what way does the Portability Analyzer even take this into account ?