~valavanisalex/ubuntu/precise/inkscape/fix-943984

« back to all changes in this revision

Viewing changes to inkscape-0.47pre1/src/gc.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Bryce Harrington
  • Date: 2009-07-02 17:09:45 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20090702170945-nn6d6zswovbwju1t
Tags: 0.47~pre1-0ubuntu1
* New upstream release.
  - Don't constrain maximization on small resolution devices (pre0)
    (LP: #348842)
  - Fixes segfault on startup (pre0)
    (LP: #391149)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/** @file
 
2
 * @brief Wrapper for Boehm GC
 
3
 */
 
4
/* Authors:
 
5
 *   MenTaLguY <mental@rydia.net>
 
6
 *
 
7
 * Copyright (C) 2004 MenTaLguY
 
8
 *
 
9
 * Released under GNU GPL, read the file 'COPYING' for more information
 
10
 */
 
11
 
 
12
#include "gc-core.h"
 
13
#include <stdexcept>
 
14
#include <cstring>
 
15
#include <string>
 
16
#include <glib/gmessages.h>
 
17
#include <sigc++/functors/ptr_fun.h>
 
18
#include <glibmm/main.h>
 
19
 
 
20
namespace Inkscape {
 
21
namespace GC {
 
22
 
 
23
namespace {
 
24
 
 
25
void display_warning(char *msg, GC_word arg) {
 
26
    g_warning(msg, arg);
 
27
}
 
28
 
 
29
void do_init() {
 
30
    GC_no_dls = 1;
 
31
    GC_all_interior_pointers = 1;
 
32
    GC_finalize_on_demand = 0;
 
33
 
 
34
    GC_INIT();
 
35
 
 
36
    GC_set_warn_proc(&display_warning);
 
37
}
 
38
 
 
39
void *debug_malloc(std::size_t size) {
 
40
    return GC_debug_malloc(size, GC_EXTRAS);
 
41
}
 
42
 
 
43
void *debug_malloc_atomic(std::size_t size) {
 
44
    return GC_debug_malloc_atomic(size, GC_EXTRAS);
 
45
}
 
46
 
 
47
void *debug_malloc_uncollectable(std::size_t size) {
 
48
    return GC_debug_malloc_uncollectable(size, GC_EXTRAS);
 
49
}
 
50
 
 
51
void *debug_malloc_atomic_uncollectable(std::size_t size) {
 
52
    return GC_debug_malloc_uncollectable(size, GC_EXTRAS);
 
53
}
 
54
 
 
55
std::ptrdiff_t compute_debug_base_fixup() {
 
56
    char *base=reinterpret_cast<char *>(GC_debug_malloc(1, GC_EXTRAS));
 
57
    char *real_base=reinterpret_cast<char *>(GC_base(base));
 
58
    GC_debug_free(base);
 
59
    return base - real_base;
 
60
}
 
61
 
 
62
inline std::ptrdiff_t const &debug_base_fixup() {
 
63
    static std::ptrdiff_t fixup=compute_debug_base_fixup();
 
64
    return fixup;
 
65
}
 
66
 
 
67
void *debug_base(void *ptr) {
 
68
    char *base=reinterpret_cast<char *>(GC_base(ptr));
 
69
    return base + debug_base_fixup();
 
70
}
 
71
 
 
72
int debug_general_register_disappearing_link(void **p_ptr, void *base) {
 
73
    char *real_base=reinterpret_cast<char *>(base) - debug_base_fixup();
 
74
    return GC_general_register_disappearing_link(p_ptr, real_base);
 
75
}
 
76
 
 
77
void dummy_do_init() {}
 
78
 
 
79
void *dummy_base(void *) { return NULL; }
 
80
 
 
81
void dummy_register_finalizer(void *, CleanupFunc, void *,
 
82
                                      CleanupFunc *old_func, void **old_data)
 
83
{
 
84
    if (old_func) {
 
85
        *old_func = NULL;
 
86
    }
 
87
    if (old_data) {
 
88
        *old_data = NULL;
 
89
    }
 
90
}
 
91
 
 
92
int dummy_general_register_disappearing_link(void **, void *) { return false; }
 
93
 
 
94
int dummy_unregister_disappearing_link(void **/*link*/) { return false; }
 
95
 
 
96
std::size_t dummy_get_heap_size() { return 0; }
 
97
 
 
98
std::size_t dummy_get_free_bytes() { return 0; }
 
99
 
 
100
void dummy_gcollect() {}
 
101
 
 
102
void dummy_enable() {}
 
103
 
 
104
void dummy_disable() {}
 
105
 
 
106
Ops enabled_ops = {
 
107
    &do_init,
 
108
    &GC_malloc,
 
109
    &GC_malloc_atomic,
 
110
    &GC_malloc_uncollectable,
 
111
    &GC_malloc_atomic_uncollectable,
 
112
    &GC_base,
 
113
    &GC_register_finalizer_ignore_self,
 
114
    &GC_general_register_disappearing_link,
 
115
    &GC_unregister_disappearing_link,
 
116
    &GC_get_heap_size,
 
117
    &GC_get_free_bytes,
 
118
    &GC_gcollect,
 
119
    &GC_enable,
 
120
    &GC_disable,
 
121
    &GC_free
 
122
};
 
123
 
 
124
Ops debug_ops = {
 
125
    &do_init,
 
126
    &debug_malloc,
 
127
    &debug_malloc_atomic,
 
128
    &debug_malloc_uncollectable,
 
129
    &debug_malloc_atomic_uncollectable,
 
130
    &debug_base,
 
131
    &GC_debug_register_finalizer_ignore_self,
 
132
    &debug_general_register_disappearing_link,
 
133
    &GC_unregister_disappearing_link,
 
134
    &GC_get_heap_size,
 
135
    &GC_get_free_bytes,
 
136
    &GC_gcollect,
 
137
    &GC_enable,
 
138
    &GC_disable,
 
139
    &GC_debug_free
 
140
};
 
141
 
 
142
Ops disabled_ops = {
 
143
    &dummy_do_init,
 
144
    &std::malloc,
 
145
    &std::malloc,
 
146
    &std::malloc,
 
147
    &std::malloc,
 
148
    &dummy_base,
 
149
    &dummy_register_finalizer,
 
150
    &dummy_general_register_disappearing_link,
 
151
    &dummy_unregister_disappearing_link,
 
152
    &dummy_get_heap_size,
 
153
    &dummy_get_free_bytes,
 
154
    &dummy_gcollect,
 
155
    &dummy_enable,
 
156
    &dummy_disable,
 
157
    &std::free
 
158
};
 
159
 
 
160
class InvalidGCModeError : public std::runtime_error {
 
161
public:
 
162
    InvalidGCModeError(const char *mode)
 
163
    : runtime_error(std::string("Unknown GC mode \"") + mode + "\"")
 
164
    {}
 
165
};
 
166
 
 
167
Ops const &get_ops() throw (InvalidGCModeError) {
 
168
    char *mode_string=std::getenv("_INKSCAPE_GC");
 
169
    if (mode_string) {
 
170
        if (!std::strcmp(mode_string, "enable")) {
 
171
            return enabled_ops;
 
172
        } else if (!std::strcmp(mode_string, "debug")) {
 
173
            return debug_ops;
 
174
        } else if (!std::strcmp(mode_string, "disable")) {
 
175
            return disabled_ops;
 
176
        } else {
 
177
            throw InvalidGCModeError(mode_string);
 
178
        }
 
179
    } else {
 
180
        return enabled_ops;
 
181
    }
 
182
}
 
183
 
 
184
void die_because_not_initialized() {
 
185
    g_error("Attempt to use GC allocator before call to Inkscape::GC::init()");
 
186
}
 
187
 
 
188
void *stub_malloc(std::size_t) {
 
189
    die_because_not_initialized();
 
190
    return NULL;
 
191
}
 
192
 
 
193
void *stub_base(void *) {
 
194
    die_because_not_initialized();
 
195
    return NULL;
 
196
}
 
197
 
 
198
void stub_register_finalizer_ignore_self(void *, CleanupFunc, void *,
 
199
                                                 CleanupFunc *, void **)
 
200
{
 
201
    die_because_not_initialized();
 
202
}
 
203
 
 
204
int stub_general_register_disappearing_link(void **, void *) {
 
205
    die_because_not_initialized();
 
206
    return 0;
 
207
}
 
208
 
 
209
int stub_unregister_disappearing_link(void **) {
 
210
    die_because_not_initialized();
 
211
    return 0;
 
212
}
 
213
 
 
214
std::size_t stub_get_heap_size() {
 
215
    die_because_not_initialized();
 
216
    return 0;
 
217
}
 
218
 
 
219
std::size_t stub_get_free_bytes() {
 
220
    die_because_not_initialized();
 
221
    return 0;
 
222
}
 
223
 
 
224
void stub_gcollect() {
 
225
    die_because_not_initialized();
 
226
}
 
227
 
 
228
void stub_enable() {
 
229
    die_because_not_initialized();
 
230
}
 
231
 
 
232
void stub_disable() {
 
233
    die_because_not_initialized();
 
234
}
 
235
 
 
236
void stub_free(void *) {
 
237
    die_because_not_initialized();
 
238
}
 
239
 
 
240
}
 
241
 
 
242
Ops Core::_ops = {
 
243
    NULL,
 
244
    &stub_malloc,
 
245
    &stub_malloc,
 
246
    &stub_malloc,
 
247
    &stub_malloc,
 
248
    &stub_base,
 
249
    &stub_register_finalizer_ignore_self,
 
250
    &stub_general_register_disappearing_link,
 
251
    &stub_unregister_disappearing_link,
 
252
    &stub_get_heap_size,
 
253
    &stub_get_free_bytes,
 
254
    &stub_gcollect,
 
255
    &stub_enable,
 
256
    &stub_disable,
 
257
    &stub_free
 
258
};
 
259
 
 
260
void Core::init() {
 
261
    try {
 
262
        _ops = get_ops();
 
263
    } catch (InvalidGCModeError &e) {
 
264
        g_warning("%s; enabling normal collection", e.what());
 
265
        _ops = enabled_ops;
 
266
    }
 
267
 
 
268
    _ops.do_init();
 
269
}
 
270
 
 
271
 
 
272
namespace {
 
273
 
 
274
bool collection_requested=false;
 
275
bool collection_task() {
 
276
    Core::gcollect();
 
277
    Core::gcollect();
 
278
    collection_requested=false;
 
279
    return false;
 
280
}
 
281
 
 
282
}
 
283
 
 
284
void request_early_collection() {
 
285
    if (!collection_requested) {
 
286
        collection_requested=true;
 
287
        Glib::signal_idle().connect(sigc::ptr_fun(&collection_task));
 
288
    }
 
289
}
 
290
 
 
291
}
 
292
}
 
293
 
 
294
/*
 
295
  Local Variables:
 
296
  mode:c++
 
297
  c-file-style:"stroustrup"
 
298
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
 
299
  indent-tabs-mode:nil
 
300
  fill-column:99
 
301
  End:
 
302
*/
 
303
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :