Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #ifdef WNT /* avoid 'std::bad_alloc' unresolved externals */
31 : : #define _CRTIMP
32 : : #define _NTSDK
33 : : #endif /* WNT */
34 : :
35 : : #include <algorithm>
36 : : #include <new>
37 : : #include <string.h>
38 : : #include <osl/diagnose.h>
39 : : #include <rtl/alloc.h>
40 : :
41 : : // =======================================================================
42 : : // AllocatorTraits
43 : : // =======================================================================
44 : :
45 : : namespace
46 : : {
47 : :
48 : : struct AllocatorTraits
49 : : {
50 : : typedef char const signature_type[8];
51 : : const signature_type & m_signature;
52 : :
53 : 0 : explicit AllocatorTraits (signature_type const & s) SAL_THROW(())
54 : 0 : : m_signature (s)
55 : 0 : {}
56 : :
57 : 0 : std::size_t size (std::size_t n) const SAL_THROW(())
58 : : {
59 : 0 : n = std::max(n, std::size_t(1));
60 : : #if OSL_DEBUG_LEVEL > 0
61 : : n += sizeof(signature_type);
62 : : #endif /* OSL_DEBUG_LEVEL */
63 : 0 : return n;
64 : : }
65 : :
66 : 0 : void* init (void * p) const SAL_THROW(())
67 : : {
68 : : #if OSL_DEBUG_LEVEL > 0
69 : : memcpy (p, m_signature, sizeof(signature_type));
70 : : p = static_cast<char*>(p) + sizeof(signature_type);
71 : : #endif /* OSL_DEBUG_LEVEL */
72 : 0 : return p;
73 : : }
74 : :
75 : 0 : void* fini (void * p) const SAL_THROW(())
76 : : {
77 : : #if OSL_DEBUG_LEVEL > 0
78 : : p = static_cast<char*>(p) - sizeof(signature_type);
79 : : if (memcmp (p, m_signature, sizeof(signature_type)) != 0)
80 : : {
81 : : OSL_FAIL("operator delete mismatch");
82 : : }
83 : : #endif /* OSL_DEBUG_LEVEL */
84 : 0 : return p;
85 : : }
86 : : };
87 : :
88 : : // =======================================================================
89 : :
90 : : struct VectorTraits : public AllocatorTraits
91 : : {
92 : : static const signature_type g_signature;
93 : :
94 : 0 : VectorTraits() SAL_THROW(())
95 : 0 : : AllocatorTraits (g_signature)
96 : 0 : {}
97 : : };
98 : :
99 : : struct ScalarTraits : public AllocatorTraits
100 : : {
101 : : static const signature_type g_signature;
102 : :
103 : 0 : ScalarTraits() SAL_THROW(())
104 : 0 : : AllocatorTraits (g_signature)
105 : 0 : {}
106 : : };
107 : :
108 : : const AllocatorTraits::signature_type VectorTraits::g_signature = "new[]()";
109 : : const AllocatorTraits::signature_type ScalarTraits::g_signature = "new() ";
110 : :
111 : : } // anonymous namespace
112 : :
113 : : // =======================================================================
114 : : // Allocator
115 : : // =======================================================================
116 : :
117 : 0 : static void default_handler (void)
118 : : {
119 : : // Multithreading race in 'std::set_new_handler()' call sequence below.
120 : 0 : throw std::bad_alloc();
121 : : }
122 : :
123 : : // =======================================================================
124 : :
125 : 0 : static void* allocate (
126 : : std::size_t n, AllocatorTraits const & rTraits)
127 : : SAL_THROW((std::bad_alloc))
128 : : {
129 : 0 : n = rTraits.size (n);
130 : 0 : for (;;)
131 : : {
132 : 0 : void * p = rtl_allocateMemory (sal_Size(n));
133 : 0 : if (p != 0)
134 : 0 : return rTraits.init (p);
135 : :
136 : 0 : std::new_handler d = default_handler, f = std::set_new_handler (d);
137 : 0 : if (f != d)
138 : 0 : std::set_new_handler (f);
139 : :
140 : 0 : if (f == 0)
141 : 0 : throw std::bad_alloc();
142 : 0 : (*f)();
143 : : }
144 : : }
145 : :
146 : : // =======================================================================
147 : :
148 : 0 : static void* allocate_nothrow (
149 : : std::size_t n, AllocatorTraits const & rTraits)
150 : : SAL_THROW(())
151 : : {
152 : : try
153 : : {
154 : 0 : return allocate (n, rTraits);
155 : : }
156 : 0 : catch (std::bad_alloc const &)
157 : : {
158 : 0 : return (0);
159 : : }
160 : : }
161 : :
162 : : // =======================================================================
163 : :
164 : 0 : static void deallocate (void * p, AllocatorTraits const & rTraits)
165 : : SAL_THROW(())
166 : : {
167 : 0 : if (p)
168 : : {
169 : 0 : rtl_freeMemory (rTraits.fini(p));
170 : : }
171 : 0 : }
172 : :
173 : : // =======================================================================
174 : : // T * p = new T; delete p;
175 : : // =======================================================================
176 : :
177 : 0 : void* SAL_CALL operator new (std::size_t n) throw (std::bad_alloc)
178 : : {
179 : 0 : return allocate (n, ScalarTraits());
180 : : }
181 : :
182 : : // =======================================================================
183 : :
184 : 0 : void SAL_CALL operator delete (void * p) throw ()
185 : : {
186 : 0 : deallocate (p, ScalarTraits());
187 : 0 : }
188 : :
189 : : // =======================================================================
190 : : // T * p = new(nothrow) T; delete(nothrow) p;
191 : : // =======================================================================
192 : :
193 : 0 : void* SAL_CALL operator new (std::size_t n, std::nothrow_t const &) throw ()
194 : : {
195 : 0 : return allocate_nothrow (n, ScalarTraits());
196 : : }
197 : :
198 : : // =======================================================================
199 : :
200 : 0 : void SAL_CALL operator delete (void * p, std::nothrow_t const &) throw ()
201 : : {
202 : 0 : deallocate (p, ScalarTraits());
203 : 0 : }
204 : :
205 : : // =======================================================================
206 : : // T * p = new T[n]; delete[] p;
207 : : // =======================================================================
208 : :
209 : 0 : void* SAL_CALL operator new[] (std::size_t n) throw (std::bad_alloc)
210 : : {
211 : 0 : return allocate (n, VectorTraits());
212 : : }
213 : :
214 : : // =======================================================================
215 : :
216 : 0 : void SAL_CALL operator delete[] (void * p) throw ()
217 : : {
218 : 0 : deallocate (p, VectorTraits());
219 : 0 : }
220 : :
221 : : // =======================================================================
222 : : // T * p = new(nothrow) T[n]; delete(nothrow)[] p;
223 : : // =======================================================================
224 : :
225 : 0 : void* SAL_CALL operator new[] (std::size_t n, std::nothrow_t const &) throw ()
226 : : {
227 : 0 : return allocate_nothrow (n, VectorTraits());
228 : : }
229 : :
230 : : // =======================================================================
231 : :
232 : 0 : void SAL_CALL operator delete[] (void * p, std::nothrow_t const &) throw ()
233 : : {
234 : 0 : deallocate (p, VectorTraits());
235 : 0 : }
236 : :
237 : : // =======================================================================
238 : :
239 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|