Update License in File Headers
[novacoin.git] / src / allocators.h
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 #ifndef BITCOIN_ALLOCATORS_H
6 #define BITCOIN_ALLOCATORS_H
7
8 #include <string.h>
9 #include <string>
10
11 #ifdef WIN32
12 #ifdef _WIN32_WINNT
13 #undef _WIN32_WINNT
14 #endif
15 #define _WIN32_WINNT 0x0501
16 #define WIN32_LEAN_AND_MEAN 1
17 #ifndef NOMINMAX
18 #define NOMINMAX
19 #endif
20 #include <windows.h>
21 // This is used to attempt to keep keying material out of swap
22 // Note that VirtualLock does not provide this as a guarantee on Windows,
23 // but, in practice, memory that has been VirtualLock'd almost never gets written to
24 // the pagefile except in rare circumstances where memory is extremely low.
25 #define mlock(p, n) VirtualLock((p), (n));
26 #define munlock(p, n) VirtualUnlock((p), (n));
27 #else
28 #include <sys/mman.h>
29 #include <limits.h>
30 /* This comes from limits.h if it's not defined there set a sane default */
31 #ifndef PAGESIZE
32 #include <unistd.h>
33 #define PAGESIZE sysconf(_SC_PAGESIZE)
34 #endif
35 #define mlock(a,b) \
36   mlock(((void *)(((size_t)(a)) & (~((PAGESIZE)-1)))),\
37   (((((size_t)(a)) + (b) - 1) | ((PAGESIZE) - 1)) + 1) - (((size_t)(a)) & (~((PAGESIZE) - 1))))
38 #define munlock(a,b) \
39   munlock(((void *)(((size_t)(a)) & (~((PAGESIZE)-1)))),\
40   (((((size_t)(a)) + (b) - 1) | ((PAGESIZE) - 1)) + 1) - (((size_t)(a)) & (~((PAGESIZE) - 1))))
41 #endif
42
43 //
44 // Allocator that locks its contents from being paged
45 // out of memory and clears its contents before deletion.
46 //
47 template<typename T>
48 struct secure_allocator : public std::allocator<T>
49 {
50     // MSVC8 default copy constructor is broken
51     typedef std::allocator<T> base;
52     typedef typename base::size_type size_type;
53     typedef typename base::difference_type  difference_type;
54     typedef typename base::pointer pointer;
55     typedef typename base::const_pointer const_pointer;
56     typedef typename base::reference reference;
57     typedef typename base::const_reference const_reference;
58     typedef typename base::value_type value_type;
59     secure_allocator() throw() {}
60     secure_allocator(const secure_allocator& a) throw() : base(a) {}
61     template <typename U>
62     secure_allocator(const secure_allocator<U>& a) throw() : base(a) {}
63     ~secure_allocator() throw() {}
64     template<typename _Other> struct rebind
65     { typedef secure_allocator<_Other> other; };
66
67     T* allocate(std::size_t n, const void *hint = 0)
68     {
69         T *p;
70         p = std::allocator<T>::allocate(n, hint);
71         if (p != NULL)
72             mlock(p, sizeof(T) * n);
73         return p;
74     }
75
76     void deallocate(T* p, std::size_t n)
77     {
78         if (p != NULL)
79         {
80             memset(p, 0, sizeof(T) * n);
81             munlock(p, sizeof(T) * n);
82         }
83         std::allocator<T>::deallocate(p, n);
84     }
85 };
86
87
88 //
89 // Allocator that clears its contents before deletion.
90 //
91 template<typename T>
92 struct zero_after_free_allocator : public std::allocator<T>
93 {
94     // MSVC8 default copy constructor is broken
95     typedef std::allocator<T> base;
96     typedef typename base::size_type size_type;
97     typedef typename base::difference_type  difference_type;
98     typedef typename base::pointer pointer;
99     typedef typename base::const_pointer const_pointer;
100     typedef typename base::reference reference;
101     typedef typename base::const_reference const_reference;
102     typedef typename base::value_type value_type;
103     zero_after_free_allocator() throw() {}
104     zero_after_free_allocator(const zero_after_free_allocator& a) throw() : base(a) {}
105     template <typename U>
106     zero_after_free_allocator(const zero_after_free_allocator<U>& a) throw() : base(a) {}
107     ~zero_after_free_allocator() throw() {}
108     template<typename _Other> struct rebind
109     { typedef zero_after_free_allocator<_Other> other; };
110
111     void deallocate(T* p, std::size_t n)
112     {
113         if (p != NULL)
114             memset(p, 0, sizeof(T) * n);
115         std::allocator<T>::deallocate(p, n);
116     }
117 };
118
119 // This is exactly like std::string, but with a custom allocator.
120 // (secure_allocator<> is defined in serialize.h)
121 typedef std::basic_string<char, std::char_traits<char>, secure_allocator<char> > SecureString;
122
123 #endif