On 2021-12-13, Kirill Frolov <
f...@fk0.name> wrote:
> Hello...
>
> I want to discuss the possibility of the implementation of some
> programming technique, which allows to use synchronization primitives,
> especially mutexes, seamlessly, like this can be done in C++ with
> std::lock_guard.
A good way to do this kind of thing is exemplified in the POSIX threads
API with thread cleanup handler management macros:
pthread_cleanup_push(function, arg);
/* if thread is cancelled here, function(arg) gets called. */
pthread_cleanup_pop(1); /* 1 -> call function(arg); 0 -> don't */
The push and pop calls have to pair.
(The Boolean argument in the pop call is clever; there are scenarios when
you don't want to call the cleanup function, or conditionally call it
based on the value of some expression.)
[snip baroque ideas]
#define LOCK(mutex) { mutex_lock(&(mutex))
#define UNLOCK(mutex) mutex_unlock(&(mutex)); }
That's the basic idea. Of course, it's hardly fool proof, e.g:
LOCK(mutex)
} /* matches open brace in LOCK */
Firstly, your editor will catch this; when you try to reindent the code,
it turns to shit. Secondly, there are a few things you can do to reduce
this threat and improve it in other ways, though I wouldn't go to too
many lengths. One simple idea:
#define LOCK(mutex) do { mutex_lock(&(mutex))
#define UNLOCK(mutex) mutex_unlock(&(mutex)); } while (0)
Now you can't close a LOCK(mutex) with just a curly brace, because
do { } is a syntax error without a while (...);.
If you want access to the mutex_lock return value, you have
to do it otherwise, like put the lock call outside of the braces:
--
TXR Programming Language:
http://nongnu.org/txr
Cygnal: Cygwin Native Application Library:
http://kylheku.com/cygnal