]> git.proxmox.com Git - mirror_frr.git/blob - doc/developer/locking.rst
doc: add developer docs for frr_with_mutex
[mirror_frr.git] / doc / developer / locking.rst
1 Locking
2 =======
3
4 FRR ships two small wrappers around ``pthread_mutex_lock()`` /
5 ``pthread_mutex_unlock``. Use ``#include "frr_pthread.h"`` to get these
6 macros.
7
8 .. c:function:: frr_with_mutex(pthread_mutex_t *mutex)
9
10 Begin a C statement block that is executed with the mutex locked. Any
11 exit from the block (``break``, ``return``, ``goto``, end of block) will
12 cause the mutex to be unlocked::
13
14 int somefunction(int option)
15 {
16 frr_with_mutex(&my_mutex) {
17 /* mutex will be locked */
18
19 if (!option)
20 /* mutex will be unlocked before return */
21 return -1;
22
23 if (something(option))
24 /* mutex will be unlocked before goto */
25 goto out_err;
26
27 somethingelse();
28
29 /* mutex will be unlocked at end of block */
30 }
31
32 return 0;
33
34 out_err:
35 somecleanup();
36 return -1;
37 }
38
39 This is a macro that internally uses a ``for`` loop. It is explicitly
40 acceptable to use ``break`` to get out of the block. Even though a single
41 statement works correctly, FRR coding style requires that this macro always
42 be used with a ``{ ... }`` block.
43
44 .. c:function:: frr_mutex_lock_autounlock(pthread_mutex_t *mutex)
45
46 Lock mutex and unlock at the end of the current C statement block::
47
48 int somefunction(int option)
49 {
50 frr_mutex_lock_autounlock(&my_mutex);
51 /* mutex will be locked */
52
53 ...
54 if (error)
55 /* mutex will be unlocked before return */
56 return -1;
57 ...
58
59 /* mutex will be unlocked before return */
60 return 0;
61 }
62
63 This is a macro that internally creates a variable with a destructor.
64 When the variable goes out of scope (i.e. the block ends), the mutex is
65 released.
66
67 .. warning::
68
69 This macro should only used when :c:func:`frr_with_mutex` would
70 result in excessively/weirdly nested code. This generally is an
71 indicator that the code might be trying to do too many things with
72 the lock held. Try any possible venues to reduce the amount of
73 code covered by the lock and move to :c:func:`frr_with_mutex`.