Mercurial > hg > pub > prymula > com
comparison DPF-Prymula-audioplugins/dpf/distrho/extra/LeakDetector.hpp @ 3:84e66ea83026
DPF-Prymula-audioplugins-0.231015-2
author | prymula <prymula76@outlook.com> |
---|---|
date | Mon, 16 Oct 2023 21:53:34 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
2:cf2cb71d31dd | 3:84e66ea83026 |
---|---|
1 /* | |
2 * DISTRHO Plugin Framework (DPF) | |
3 * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |
4 * | |
5 * Permission to use, copy, modify, and/or distribute this software for any purpose with | |
6 * or without fee is hereby granted, provided that the above copyright notice and this | |
7 * permission notice appear in all copies. | |
8 * | |
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |
10 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |
11 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |
12 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |
13 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
15 */ | |
16 | |
17 #ifndef DISTRHO_LEAK_DETECTOR_HPP_INCLUDED | |
18 #define DISTRHO_LEAK_DETECTOR_HPP_INCLUDED | |
19 | |
20 #include "../DistrhoUtils.hpp" | |
21 | |
22 START_NAMESPACE_DISTRHO | |
23 | |
24 // ----------------------------------------------------------------------- | |
25 // The following code was based from juce-core LeakDetector class | |
26 | |
27 /** | |
28 Copyright (C) 2013 Raw Material Software Ltd. | |
29 | |
30 Permission is granted to use this software under the terms of the ISC license | |
31 http://www.isc.org/downloads/software-support-policy/isc-license/ | |
32 | |
33 Permission to use, copy, modify, and/or distribute this software for any | |
34 purpose with or without fee is hereby granted, provided that the above | |
35 copyright notice and this permission notice appear in all copies. | |
36 | |
37 THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD | |
38 TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |
39 FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, | |
40 OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF | |
41 USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |
42 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |
43 OF THIS SOFTWARE. | |
44 */ | |
45 | |
46 /** A good old-fashioned C macro concatenation helper. | |
47 This combines two items (which may themselves be macros) into a single string, | |
48 avoiding the pitfalls of the ## macro operator. | |
49 */ | |
50 #define DISTRHO_JOIN_MACRO_HELPER(a, b) a ## b | |
51 #define DISTRHO_JOIN_MACRO(item1, item2) DISTRHO_JOIN_MACRO_HELPER(item1, item2) | |
52 | |
53 #if defined(DEBUG) && !defined(NDEBUG) | |
54 /** This macro lets you embed a leak-detecting object inside a class.\n | |
55 To use it, simply declare a DISTRHO_LEAK_DETECTOR(YourClassName) inside a private section | |
56 of the class declaration. E.g. | |
57 \code | |
58 class MyClass | |
59 { | |
60 public: | |
61 MyClass(); | |
62 void blahBlah(); | |
63 | |
64 private: | |
65 DISTRHO_LEAK_DETECTOR(MyClass) | |
66 }; | |
67 \endcode | |
68 */ | |
69 # define DISTRHO_LEAK_DETECTOR(ClassName) \ | |
70 friend class DISTRHO_NAMESPACE::LeakedObjectDetector<ClassName>; \ | |
71 static const char* getLeakedObjectClassName() noexcept { return #ClassName; } \ | |
72 DISTRHO_NAMESPACE::LeakedObjectDetector<ClassName> DISTRHO_JOIN_MACRO(leakDetector_, ClassName); | |
73 | |
74 # define DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ClassName) \ | |
75 DISTRHO_DECLARE_NON_COPYABLE(ClassName) \ | |
76 DISTRHO_LEAK_DETECTOR(ClassName) | |
77 #else | |
78 /** Don't use leak detection on release builds. */ | |
79 # define DISTRHO_LEAK_DETECTOR(ClassName) | |
80 # define DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ClassName) \ | |
81 DISTRHO_DECLARE_NON_COPYABLE(ClassName) | |
82 #endif | |
83 | |
84 //============================================================================== | |
85 /** | |
86 Embedding an instance of this class inside another class can be used as a low-overhead | |
87 way of detecting leaked instances. | |
88 | |
89 This class keeps an internal static count of the number of instances that are | |
90 active, so that when the app is shutdown and the static destructors are called, | |
91 it can check whether there are any left-over instances that may have been leaked. | |
92 | |
93 To use it, use the DISTRHO_LEAK_DETECTOR macro as a simple way to put one in your | |
94 class declaration. | |
95 */ | |
96 template<class OwnerClass> | |
97 class LeakedObjectDetector | |
98 { | |
99 public: | |
100 //============================================================================== | |
101 LeakedObjectDetector() noexcept { ++(getCounter().numObjects); } | |
102 LeakedObjectDetector(const LeakedObjectDetector&) noexcept { ++(getCounter().numObjects); } | |
103 | |
104 ~LeakedObjectDetector() noexcept | |
105 { | |
106 if (--(getCounter().numObjects) < 0) | |
107 { | |
108 /** If you hit this, then you've managed to delete more instances of this class than you've | |
109 created.. That indicates that you're deleting some dangling pointers. | |
110 | |
111 Note that although this assertion will have been triggered during a destructor, it might | |
112 not be this particular deletion that's at fault - the incorrect one may have happened | |
113 at an earlier point in the program, and simply not been detected until now. | |
114 | |
115 Most errors like this are caused by using old-fashioned, non-RAII techniques for | |
116 your object management. Tut, tut. Always, always use ScopedPointers, OwnedArrays, | |
117 ReferenceCountedObjects, etc, and avoid the 'delete' operator at all costs! | |
118 */ | |
119 d_stderr2("*** Dangling pointer deletion! Class: '%s', Count: %i", getLeakedObjectClassName(), getCounter().numObjects); | |
120 } | |
121 } | |
122 | |
123 private: | |
124 //============================================================================== | |
125 class LeakCounter | |
126 { | |
127 public: | |
128 LeakCounter() noexcept | |
129 : numObjects(0) {} | |
130 | |
131 ~LeakCounter() noexcept | |
132 { | |
133 if (numObjects > 0) | |
134 { | |
135 /** If you hit this, then you've leaked one or more objects of the type specified by | |
136 the 'OwnerClass' template parameter - the name should have been printed by the line above. | |
137 | |
138 If you're leaking, it's probably because you're using old-fashioned, non-RAII techniques for | |
139 your object management. Tut, tut. Always, always use ScopedPointers, OwnedArrays, | |
140 ReferenceCountedObjects, etc, and avoid the 'delete' operator at all costs! | |
141 */ | |
142 d_stderr2("*** Leaked objects detected: %i instance(s) of class '%s'", numObjects, getLeakedObjectClassName()); | |
143 } | |
144 } | |
145 | |
146 // this should be an atomic... | |
147 volatile int numObjects; | |
148 }; | |
149 | |
150 static const char* getLeakedObjectClassName() noexcept | |
151 { | |
152 return OwnerClass::getLeakedObjectClassName(); | |
153 } | |
154 | |
155 static LeakCounter& getCounter() noexcept | |
156 { | |
157 static LeakCounter counter; | |
158 return counter; | |
159 } | |
160 }; | |
161 | |
162 // ----------------------------------------------------------------------- | |
163 | |
164 END_NAMESPACE_DISTRHO | |
165 | |
166 #endif // DISTRHO_LEAK_DETECTOR_HPP_INCLUDED |