A. - Quick response
Assuming you have a Mutex and Lock object (your mileage may vary):
#define MY_OWN_LOCK(mm_mutex) \ \ if(bool b_1227F2B8_136B_11E1_973D_7D0B4924019B = false) \ ; \ else \ for(Lock lock_1227F2B8_136B_11E1_973D_7D0B4924019B(mm_mutex); \ !b_1227F2B8_136B_11E1_973D_7D0B4924019B; \ b_1227F2B8_136B_11E1_973D_7D0B4924019B = true)
which can be used as:
Mutex mutex ; void foo() {
B. - Detailed answer
It depends on the library you will be using.
B.1 - Prerequisites
Suppose you have:
- a
Mutex object that has lock() and unlock() methods - a
Lock , which has a constructor with the Mutex as parameter and calls its lock() method when building, and the unlock() method when it is destroyed
So you have something like:
class Mutex { public : lock() ; unlock() ;
B.2 - Using Raw C +
If you are not familiar with C ++ RAII, your code will look like this:
void foo() { // not locked mutex.lock() ; // locked ! mutex.unlock() ; // not locked }
This code is so flawed that I will never discuss it (Google "exception safety" if necessary).
B.3 - Using Raw C ++
void foo() {
B.4 - Using C ++ with Macro Photography
With the following macro:
#define LOCK(mm_mutex) \ \ if(bool b = false) \ ; \ else \ for(Lock lock(mm_mutex); !b; b = true)
You can write:
void foo() {
B.5 - Why is it so complicated?
Most lock macros rely on the lock object to be tested. This either requires the implementation of Safe Bool Idiom (which is redundant for current use), or the need to lock the lock object for bool , which brings its own (large) set of flaws to the class.
In the current implementation, if used to declare a logical element that will control the body of for , while for itself is used to declare the Lock object itself.
I believe this template is called something like "C ++ variable injection."
B.6 - Performance?
Please note that you are blocking something, so the code inside mutex.lock() and mutex.unlock() will take much more cycles than anything in the macro.
In non-optimized assemblies, if and for jumps will be displayed (for example, try phasing in the visual debugger), but in an optimized assembly all if and for will be optimized (there is no difference between the assembly generated by "raw C ++ usage" and "using using extended C ++ macros. "
B.7 - Attention!
The macro above is simplified for educational purposes. To use it for production code, you must:
- "namespace" is the name of the macro (that is, prefixing it with some unique name, like
BOOST_ part of the macro BOOST_FOREACH ) - make logical
b and Lock variable "unique" to make sure that they will not interfere with the user code. I usually use the suffix GUID / UUID for this (e.g. b_ABCD_ABCD_AB_ABCDEF and lock_ABCD_ABCD_AB_ABCDEF )
B.8 - Sources
I first saw this model in an article (I believe Andrei Alexandrescu), and indeed, I was looking for it when I came across this SO question.
:-)
As soon as I find the source, I will update this answer with the correct link.
Edit: Source found !!!