How can I find from mutex handle in C# that a mutex is acquired?
When mutex.WaitOne(timeout)
timeouts, it returns false
. However, how can I find that from the mutex handle? (Maybe using p/invoke.)
UPDATE:
public class InterProcessLock : IDisposable { readonly Mutex mutex; public bool IsAcquired { get; private set; } public InterProcessLock(string name, TimeSpan timeout) { bool created; var security = new MutexSecurity(); security.AddAccessRule(new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Allow)); mutex = new Mutex(false, name, out created, security); IsAcquired = mutex.WaitOne(timeout); } #region IDisposable Members public void Dispose() { if (IsAcquired) { mutex.ReleaseMutex(); IsAcquired = false; } } #endregion }
Currently, I am using my own property IsAcquired
to determine whether I should release a mutex. Not essential but clearer, would be not to use a secondary copy of the information represented by IsAcquired
property, but rather to ask directly the mutex whether it is acquired by me. Since calling mutex.ReleaseMutex()
throws an exception if it is not acquired by me.
(By acquired state I mean that the mutex is in not-signaled state when I am owning the mutex.)
(EDIT: I have added IsAcquired = false;
thanks to mattdekrey's post.)
std::mutex::try_lock If the mutex is currently locked by another thread, the function fails and returns false , without blocking (the calling thread continues its execution). If the mutex is currently locked by the same thread calling this function, it produces a deadlock (with undefined behavior).
A Mutex is a lock that we set before using a shared resource and release after using it. When the lock is set, no other thread can access the locked region of code.
The following is an example of creating and using a recursive mutex type: pthread_mutexattr_t attr; pthread_mutex_t mutex; pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&mutex, &attr); struct { int a; int b; int c; } A; f() { pthread_mutex_lock(&mutex); A.a++; g(); A.c = 0; ...
A mutex must be created by the MutexCreate function before this function can get its handle. If the mutex is not created, an error is returned. If the threads using a mutex in an application share memory, the handle of a mutex may be stored in the shared memory by the thread creating the mutex.
The reason there is no clean way to do this is because it is not a good idea and the reason is because race conditions are -very- easy to introduce when you rely on this type of logic. So your design needs to change.
First, you should not acquire a lock in a constructor. Turn this class into a factory that returns a properly initialized mutex object. That way you can know if you acquired the lock or not.
DO NOT rely on Dispose to release locks, this is asking for deadlock ridden code that is hard to maintain. Use a try/finally block to ensure it is released.
Timeouts are a bit sketchy. Only use timeouts when not acquiring the lock would be considered normal operation. Not being able to acquire the lock is usually a bug and merely avoiding it with timeouts hides the bug. If you need timeouts, consider using an event (maybe AutoResetEvent), this may be more appropriate.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With