]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/security/LockingPointer.h
2 * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
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.
9 #ifndef SQUID_SRC_SECURITY_LOCKINGPOINTER_H
10 #define SQUID_SRC_SECURITY_LOCKINGPOINTER_H
12 #include "base/TidyPointer.h"
16 #if HAVE_OPENSSL_CRYPTO_H
17 #include <openssl/crypto.h>
20 // Macro to be used to define the C++ wrapper function of a sk_*_pop_free
21 // openssl family functions. The C++ function suffixed with the _free_wrapper
23 #define sk_free_wrapper(sk_object, argument, freefunction) \
24 extern "C++" inline void sk_object ## _free_wrapper(argument a) { \
25 sk_object ## _pop_free(a, freefunction); \
30 #include "base/Lock.h"
31 #include <unordered_map>
35 // Macro to be used to define the C++ equivalent function of an extern "C"
36 // function. The C++ function suffixed with the _cpp extension
37 #define CtoCpp1(function, argument) \
38 extern "C++" inline void function ## _cpp(argument a) { \
46 * Add SSL locking (a.k.a. reference counting) and assignment to TidyPointer
48 template <typename T
, void (*DeAllocator
)(T
*t
), int lock
>
49 class LockingPointer
: public TidyPointer
<T
, DeAllocator
>
52 typedef TidyPointer
<T
, DeAllocator
> Parent
;
53 typedef LockingPointer
<T
, DeAllocator
, lock
> SelfType
;
55 explicit LockingPointer(T
*t
= nullptr): Parent() {reset(t
);}
57 virtual ~LockingPointer() { Parent::reset(nullptr); }
59 explicit LockingPointer(const SelfType
&o
): Parent() {
63 SelfType
&operator =(const SelfType
& o
) {
68 explicit LockingPointer(LockingPointer
<T
, DeAllocator
, lock
> &&o
): Parent(o
.release()) {}
70 LockingPointer
<T
, DeAllocator
, lock
> &operator =(LockingPointer
<T
, DeAllocator
, lock
> &&o
) {
71 if (o
.get() != this->get())
72 this->reset(o
.release());
76 virtual void reset(T
*t
) {
81 // OpenSSL maintains the reference locks through calls to Deallocator
82 // our manual locking does not have that luxury
84 if (SelfType::Locks().at(this->get()).unlock())
85 SelfType::Locks().erase(this->get());
92 CRYPTO_add(&t
->references
, 1, lock
);
94 SelfType::Locks()[t
].lock(); // find/create and lock
101 // since we can never be sure if a raw-* passed to us is already being
102 // lock counted by another LockingPointer<> and the types pointed to are
103 // defined by third-party libraries we have to maintain the locks in a
104 // type-specific static external to both the Pointer and base classes.
105 static std::unordered_map
<T
*, Lock
> & Locks() {
106 static std::unordered_map
<T
*, Lock
> Instance
;
112 } // namespace Security
114 #endif /* SQUID_SRC_SECURITY_LOCKINGPOINTER_H */