]> git.ipfire.org Git - thirdparty/squid.git/blob - src/security/LockingPointer.h
Bug 4438 pt2: Fix destructor sequence issues in old memory pools (partial)
[thirdparty/squid.git] / src / security / LockingPointer.h
1 /*
2 * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9 #ifndef SQUID_SRC_SECURITY_LOCKINGPOINTER_H
10 #define SQUID_SRC_SECURITY_LOCKINGPOINTER_H
11
12 #include "base/TidyPointer.h"
13
14 #if USE_OPENSSL
15 #if HAVE_OPENSSL_CRYPTO_H
16 #include <openssl/crypto.h>
17 #endif
18
19 // Macro to be used to define the C++ wrapper function of a sk_*_pop_free
20 // openssl family functions. The C++ function suffixed with the _free_wrapper
21 // extension
22 #define sk_free_wrapper(sk_object, argument, freefunction) \
23 extern "C++" inline void sk_object ## _free_wrapper(argument a) { \
24 sk_object ## _pop_free(a, freefunction); \
25 }
26
27 #endif
28
29 // Macro to be used to define the C++ equivalent function of an extern "C"
30 // function. The C++ function suffixed with the _cpp extension
31 #define CtoCpp1(function, argument) \
32 extern "C++" inline void function ## _cpp(argument a) { \
33 function(a); \
34 }
35
36 namespace Security
37 {
38
39 /**
40 * Add SSL locking (a.k.a. reference counting) and assignment to TidyPointer
41 */
42 template <typename T, void (*DeAllocator)(T *t), int lock>
43 class LockingPointer: public TidyPointer<T, DeAllocator>
44 {
45 public:
46 typedef TidyPointer<T, DeAllocator> Parent;
47 typedef LockingPointer<T, DeAllocator, lock> SelfType;
48
49 explicit LockingPointer(T *t = nullptr): Parent(t) {}
50
51 explicit LockingPointer(const SelfType &o): Parent() {
52 resetAndLock(o.get());
53 }
54
55 SelfType &operator =(const SelfType & o) {
56 resetAndLock(o.get());
57 return *this;
58 }
59
60 #if __cplusplus >= 201103L
61 explicit LockingPointer(LockingPointer<T, DeAllocator, lock> &&o): Parent(o.release()) {
62 }
63
64 LockingPointer<T, DeAllocator, lock> &operator =(LockingPointer<T, DeAllocator, lock> &&o) {
65 if (o.get() != this->get())
66 this->reset(o.release());
67 return *this;
68 }
69 #endif
70
71 void resetAndLock(T *t) {
72 if (t != this->get()) {
73 this->reset(t);
74 #if USE_OPENSSL
75 if (t)
76 CRYPTO_add(&t->references, 1, lock);
77 #elif USE_GNUTLS
78 // XXX: GnuTLS does not provide locking ?
79 #else
80 assert(false);
81 #endif
82 }
83 }
84 };
85
86 } // namespace Security
87
88 #endif /* SQUID_SRC_SECURITY_LOCKINGPOINTER_H */
89