0

Before a thread locks a mutex, I want to check whether it has already got a lock on that mutex so I can't do this:

Acquire mutex
Acquire mutex

// do something here

Release mutex

// still has mutex lock at this point!!

I know I could just use a bool here, but wanted to know if something already exists.

Thanks.

Cheetah
  • 13,785
  • 31
  • 106
  • 190

5 Answers5

1

Too long for a comment, so apologies this is an answer..

IMO, any design which calls for recursive locking is likely to end nasal daemons. Redesign you code so that the same lock does not have to be acquired multiple times by the same thread. IMO a good practice is to never call public functions (which should lock) from other public functions (which also lock), and all private functions should never lock - i.e. they can only be called by the public methods (which are locked).

So re-organize your code such that methods called in the context of the same thread have one entry point into your object, which then locks, and any subsequent private function calls can operate under this lock. There are some disadvantages with this approach (for example multiple lock operations for sequential function calls - but if this is proved to be a bottleneck via profiling, then adopt a pattern where you expose the mutex via a member, and as one person mentioned already use RAII to lock that lock for the duration of the function calls.)

All-in-all, avoid recursive mutexes if you can...

Nim
  • 33,299
  • 2
  • 62
  • 101
0

If you a are using win32 :

After a thread obtains ownership of a mutex, it can specify the same mutex in repeated calls to the wait-functions without blocking its execution. This prevents a thread from deadlocking itself while waiting for a mutex that it already owns. To release its ownership under such circumstances, the thread must call ReleaseMutex once for each time that the mutex satisfied the conditions of a wait function.

source: Mutex Objects - Microsoft Documentation

Mustafa
  • 5,624
  • 3
  • 24
  • 40
Asen
  • 62
  • 5
0

Investigate RAII. That'll stop you worrying about that problem.

Paul Mitchell
  • 3,241
  • 1
  • 19
  • 22
  • Suggesting wrap it in a class/structure with an extra bool for if its locked or not?...(that comment may be slightly premature after a 5 minute google as to what RAII is) – Cheetah Feb 01 '12 at 12:52
  • +1. Paul's suggestion is good. That class would have a single member - a mutex (reference). Acquire in constructor, Release in destructor. Exception-safe and no need for any bool. Have a look an example in the first answer here: http://stackoverflow.com/questions/161177/does-c-support-finally-blocks-and-whats-this-raii-i-keep-hearing-about – Bojan Komazec Feb 01 '12 at 13:10
  • 3
    I don't see how this will help here. A recursive call will not cause the RAII release aspect to be triggered prior to the next invocation. – edA-qa mort-ora-y Feb 01 '12 at 14:40
  • The OPs concern seems to be that he's afraid of locking twice and only unlocking once. RAII won't stop him locking recursively, but it'll ensure that his locks are matched by his unlocks. – Paul Mitchell Feb 01 '12 at 16:14
0

What API do you use? It is important because if it is e.g. Win32 API double call to WaitForSingleObject in one thread on one mutex you don't have to call ReleaseMutex two times.

However this is risky code anyway

Alex Z
  • 1,867
  • 1
  • 29
  • 27
0

If you're using a specific platform (Win32?) mutex implementation - then you should consult that platform's documentation.

If you're using C++11 standard mutex - std::mutex, switch to std::recursive_mutex instead. Note that you'll need to call unlock() for each call to lock().

Asaf
  • 4,317
  • 28
  • 48