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