7ff17870e1ea306c0e4bfbe9074428bf201c46be
[metze/wireshark/wip.git] / epan / wmem / wmem_scopes.c
1 /* wmem_scopes.c
2  * Wireshark Memory Manager Scopes
3  * Copyright 2012, Evan Huus <eapache@gmail.com>
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23
24 #include <glib.h>
25
26 #include "wmem_core.h"
27 #include "wmem_scopes.h"
28 #include "wmem_allocator.h"
29
30 /* One of the supposed benefits of wmem over the old emem was going to be that
31  * the scoping of the various memory pools would be obvious, since they would
32  * no longer be global. Instead, the pools would be managed as variables scoped
33  * by the compiler, so functions outside of that scope wouldn't have access to
34  * the pools and wouldn't be able to allocate memory in a scope to which they
35  * didn't belong.
36  *
37  * That idea fell apart rather quickly :P
38  *
39  * The principle still stands, and most pools should be managed in that way.
40  * The three in this file are *exceptions*. They are the three scopes that emem
41  * provided as globals. Converting all of the code that used them to pass an
42  * extra parameter (or three) around would have been a nightmare of epic
43  * proportions, so we provide these three as globals still.
44  *
45  * We do, however, use some extra booleans and a mountain of assertions to try
46  * and catch anybody accessing the pools out of the correct scope. It's not
47  * perfect, but it should stop most of the bad behaviour that emem permitted.
48  */
49
50 /* TODO: Make these thread-local */
51 static wmem_allocator_t *packet_scope = NULL;
52 static wmem_allocator_t *file_scope   = NULL;
53 static wmem_allocator_t *epan_scope   = NULL;
54
55 /* Packet Scope */
56
57 wmem_allocator_t *
58 wmem_packet_scope(void)
59 {
60     g_assert(packet_scope);
61
62     return packet_scope;
63 }
64
65 void
66 wmem_enter_packet_scope(void)
67 {
68     g_assert(packet_scope);
69     g_assert(file_scope->in_scope);
70     g_assert(!packet_scope->in_scope);
71
72     packet_scope->in_scope = TRUE;
73 }
74
75 void
76 wmem_leave_packet_scope(void)
77 {
78     g_assert(packet_scope);
79     g_assert(packet_scope->in_scope);
80
81     wmem_free_all(packet_scope);
82     packet_scope->in_scope = FALSE;
83 }
84
85 /* File Scope */
86
87 wmem_allocator_t *
88 wmem_file_scope(void)
89 {
90     g_assert(file_scope);
91
92     return file_scope;
93 }
94
95 void
96 wmem_enter_file_scope(void)
97 {
98     g_assert(file_scope);
99     g_assert(!file_scope->in_scope);
100
101     file_scope->in_scope = TRUE;
102 }
103
104 void
105 wmem_leave_file_scope(void)
106 {
107     g_assert(file_scope);
108     g_assert(file_scope->in_scope);
109     g_assert(!packet_scope->in_scope);
110
111     wmem_free_all(file_scope);
112     file_scope->in_scope = FALSE;
113
114     /* this seems like a good time to do garbage collection */
115     wmem_gc(file_scope);
116     wmem_gc(packet_scope);
117 }
118
119 /* Epan Scope */
120
121 wmem_allocator_t *
122 wmem_epan_scope(void)
123 {
124     g_assert(epan_scope);
125
126     return epan_scope;
127 }
128
129 /* Scope Management */
130
131 void
132 wmem_init_scopes(void)
133 {
134     g_assert(packet_scope == NULL);
135     g_assert(file_scope   == NULL);
136     g_assert(epan_scope   == NULL);
137
138     packet_scope = wmem_allocator_new(WMEM_ALLOCATOR_BLOCK_FAST);
139     file_scope   = wmem_allocator_new(WMEM_ALLOCATOR_BLOCK);
140     epan_scope   = wmem_allocator_new(WMEM_ALLOCATOR_SIMPLE);
141
142     /* Scopes are initialized to TRUE by default on creation */
143     packet_scope->in_scope = FALSE;
144     file_scope->in_scope   = FALSE;
145 }
146
147 void
148 wmem_cleanup_scopes(void)
149 {
150     g_assert(packet_scope);
151     g_assert(file_scope);
152     g_assert(epan_scope);
153
154     g_assert(packet_scope->in_scope == FALSE);
155     g_assert(file_scope->in_scope   == FALSE);
156
157     wmem_destroy_allocator(packet_scope);
158     wmem_destroy_allocator(file_scope);
159     wmem_destroy_allocator(epan_scope);
160
161     packet_scope = NULL;
162     file_scope   = NULL;
163     epan_scope   = NULL;
164 }
165
166 /*
167  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
168  *
169  * Local variables:
170  * c-basic-offset: 4
171  * tab-width: 8
172  * indent-tabs-mode: nil
173  * End:
174  *
175  * vi: set shiftwidth=4 tabstop=8 expandtab:
176  * :indentSize=4:tabSize=8:noTabs=true:
177  */