]> git.ipfire.org Git - thirdparty/squid.git/blob - src/security/LockingPointer.h
SourceFormat Enforcement
[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.get()) {
62 *o.addr() = nullptr;
63 }
64
65 LockingPointer<T, DeAllocator, lock> &operator =(LockingPointer<T, DeAllocator, lock> &&o) {
66 if (o.get() != this->get()) {
67 this->reset(o.get());
68 *o.addr() = nullptr;
69 }
70 return *this;
71 }
72 #endif
73
74 void resetAndLock(T *t) {
75 if (t != this->get()) {
76 this->reset(t);
77 #if USE_OPENSSL
78 if (t)
79 CRYPTO_add(&t->references, 1, lock);
80 #elif USE_GNUTLS
81 // XXX: GnuTLS does not provide locking ?
82 #else
83 assert(false);
84 #endif
85 }
86 }
87 };
88
89 } // namespace Security
90
91 #endif /* SQUID_SRC_SECURITY_LOCKINGPOINTER_H */
92