1 | //////////////////////////////////////////////////////////// |
2 | // |
3 | // SFML - Simple and Fast Multimedia Library |
4 | // Copyright (C) 2007-2020 Laurent Gomila (laurent@sfml-dev.org) |
5 | // |
6 | // This software is provided 'as-is', without any express or implied warranty. |
7 | // In no event will the authors be held liable for any damages arising from the use of this software. |
8 | // |
9 | // Permission is granted to anyone to use this software for any purpose, |
10 | // including commercial applications, and to alter it and redistribute it freely, |
11 | // subject to the following restrictions: |
12 | // |
13 | // 1. The origin of this software must not be misrepresented; |
14 | // you must not claim that you wrote the original software. |
15 | // If you use this software in a product, an acknowledgment |
16 | // in the product documentation would be appreciated but is not required. |
17 | // |
18 | // 2. Altered source versions must be plainly marked as such, |
19 | // and must not be misrepresented as being the original software. |
20 | // |
21 | // 3. This notice may not be removed or altered from any source distribution. |
22 | // |
23 | //////////////////////////////////////////////////////////// |
24 | |
25 | #ifndef SFML_LOCK_HPP |
26 | #define SFML_LOCK_HPP |
27 | |
28 | //////////////////////////////////////////////////////////// |
29 | // Headers |
30 | //////////////////////////////////////////////////////////// |
31 | #include <SFML/System/Export.hpp> |
32 | #include <SFML/System/NonCopyable.hpp> |
33 | |
34 | |
35 | namespace sf |
36 | { |
37 | class Mutex; |
38 | |
39 | //////////////////////////////////////////////////////////// |
40 | /// \brief Automatic wrapper for locking and unlocking mutexes |
41 | /// |
42 | //////////////////////////////////////////////////////////// |
43 | class SFML_SYSTEM_API Lock : NonCopyable |
44 | { |
45 | public: |
46 | |
47 | //////////////////////////////////////////////////////////// |
48 | /// \brief Construct the lock with a target mutex |
49 | /// |
50 | /// The mutex passed to sf::Lock is automatically locked. |
51 | /// |
52 | /// \param mutex Mutex to lock |
53 | /// |
54 | //////////////////////////////////////////////////////////// |
55 | explicit Lock(Mutex& mutex); |
56 | |
57 | //////////////////////////////////////////////////////////// |
58 | /// \brief Destructor |
59 | /// |
60 | /// The destructor of sf::Lock automatically unlocks its mutex. |
61 | /// |
62 | //////////////////////////////////////////////////////////// |
63 | ~Lock(); |
64 | |
65 | private: |
66 | |
67 | //////////////////////////////////////////////////////////// |
68 | // Member data |
69 | //////////////////////////////////////////////////////////// |
70 | Mutex& m_mutex; //!< Mutex to lock / unlock |
71 | }; |
72 | |
73 | } // namespace sf |
74 | |
75 | |
76 | #endif // SFML_LOCK_HPP |
77 | |
78 | |
79 | //////////////////////////////////////////////////////////// |
80 | /// \class sf::Lock |
81 | /// \ingroup system |
82 | /// |
83 | /// sf::Lock is a RAII wrapper for sf::Mutex. By unlocking |
84 | /// it in its destructor, it ensures that the mutex will |
85 | /// always be released when the current scope (most likely |
86 | /// a function) ends. |
87 | /// This is even more important when an exception or an early |
88 | /// return statement can interrupt the execution flow of the |
89 | /// function. |
90 | /// |
91 | /// For maximum robustness, sf::Lock should always be used |
92 | /// to lock/unlock a mutex. |
93 | /// |
94 | /// Usage example: |
95 | /// \code |
96 | /// sf::Mutex mutex; |
97 | /// |
98 | /// void function() |
99 | /// { |
100 | /// sf::Lock lock(mutex); // mutex is now locked |
101 | /// |
102 | /// functionThatMayThrowAnException(); // mutex is unlocked if this function throws |
103 | /// |
104 | /// if (someCondition) |
105 | /// return; // mutex is unlocked |
106 | /// |
107 | /// } // mutex is unlocked |
108 | /// \endcode |
109 | /// |
110 | /// Because the mutex is not explicitly unlocked in the code, |
111 | /// it may remain locked longer than needed. If the region |
112 | /// of the code that needs to be protected by the mutex is |
113 | /// not the entire function, a good practice is to create a |
114 | /// smaller, inner scope so that the lock is limited to this |
115 | /// part of the code. |
116 | /// |
117 | /// \code |
118 | /// sf::Mutex mutex; |
119 | /// |
120 | /// void function() |
121 | /// { |
122 | /// { |
123 | /// sf::Lock lock(mutex); |
124 | /// codeThatRequiresProtection(); |
125 | /// |
126 | /// } // mutex is unlocked here |
127 | /// |
128 | /// codeThatDoesntCareAboutTheMutex(); |
129 | /// } |
130 | /// \endcode |
131 | /// |
132 | /// Having a mutex locked longer than required is a bad practice |
133 | /// which can lead to bad performances. Don't forget that when |
134 | /// a mutex is locked, other threads may be waiting doing nothing |
135 | /// until it is released. |
136 | /// |
137 | /// \see sf::Mutex |
138 | /// |
139 | //////////////////////////////////////////////////////////// |
140 | |