2 * reactos Cache Manager (Cc*) PrivateBcb Map type structure of libcaptive
3 * Copyright (C) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; exactly version 2 of June 1991 is required
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "privatebcbpin.h" /* self */
23 #include "privatebcb.h"
24 #include "privatebcb-priv.h"
25 #include "sharedcachemap-priv.h"
26 #include <glib-object.h>
27 #include "captive/macros.h"
30 struct _CaptivePrivateBcbPinObject {
31 CaptivePrivateBcbObject parent_instance;
33 gulong FileSizes_changed_handler_id;
34 gulong FileSizes_changed_after_handler_id;
35 gulong purge_handler_id;
38 struct _CaptivePrivateBcbPinObjectClass {
39 CaptivePrivateBcbObjectClass parent_class;
43 static gpointer captive_private_bcb_pin_object_parent_class=NULL;
46 static void captive_private_bcb_pin_object_finalize(CaptivePrivateBcbPinObject *captive_private_bcb_pin_object)
48 CaptivePrivateBcbObject *captive_private_bcb_object;
49 CaptiveSharedCacheMapObject *SharedCacheMap;
52 g_return_if_fail(captive_private_bcb_pin_object!=NULL);
54 captive_private_bcb_object=CAPTIVE_PRIVATE_BCB_OBJECT(captive_private_bcb_pin_object);
56 if (captive_private_bcb_pin_object->FileSizes_changed_handler_id) {
57 g_assert(captive_private_bcb_object->SharedCacheMap!=NULL);
58 g_signal_handler_disconnect(
59 captive_private_bcb_object->SharedCacheMap, /* instance */
60 captive_private_bcb_pin_object->FileSizes_changed_handler_id);
61 captive_private_bcb_pin_object->FileSizes_changed_handler_id=0;
63 if (captive_private_bcb_pin_object->FileSizes_changed_after_handler_id) {
64 g_assert(captive_private_bcb_object->SharedCacheMap!=NULL);
65 g_signal_handler_disconnect(
66 captive_private_bcb_object->SharedCacheMap, /* instance */
67 captive_private_bcb_pin_object->FileSizes_changed_after_handler_id);
68 captive_private_bcb_pin_object->FileSizes_changed_after_handler_id=0;
70 if (captive_private_bcb_pin_object->purge_handler_id) {
71 g_assert(captive_private_bcb_object->SharedCacheMap!=NULL);
72 g_signal_handler_disconnect(
73 captive_private_bcb_object->SharedCacheMap, /* instance */
74 captive_private_bcb_pin_object->purge_handler_id);
75 captive_private_bcb_pin_object->purge_handler_id=0;
77 if ((SharedCacheMap=captive_private_bcb_object->SharedCacheMap)) {
78 if ((pin_hash=SharedCacheMap->pin_hash)) {
79 /* Do not: g_assert(g_hash_table_lookup(pin_hash,&captive_private_bcb_object->offset));
80 * as we may be captive_private_bcb_pin_object_detach_pin()ed.
82 if (captive_private_bcb_object==g_hash_table_lookup(pin_hash,&captive_private_bcb_pin_object->offset))
83 g_hash_table_remove(pin_hash,&captive_private_bcb_pin_object->offset);
87 G_OBJECT_CLASS(captive_private_bcb_pin_object_parent_class)->finalize((GObject *)captive_private_bcb_pin_object);
91 static void captive_private_bcb_pin_object_class_init(CaptivePrivateBcbPinObjectClass *class)
93 GObjectClass *gobject_class=G_OBJECT_CLASS(class);
95 captive_private_bcb_pin_object_parent_class=g_type_class_ref(G_TYPE_OBJECT);
96 gobject_class->finalize=(void (*)(GObject *object))captive_private_bcb_pin_object_finalize;
99 static void captive_private_bcb_pin_object_init(CaptivePrivateBcbPinObject *captive_private_bcb_pin_object)
103 GType captive_private_bcb_pin_object_get_type(void)
105 static GType captive_private_bcb_pin_object_type=0;
107 if (!captive_private_bcb_pin_object_type) {
108 static const GTypeInfo captive_private_bcb_pin_object_info={
109 sizeof(CaptivePrivateBcbPinObjectClass),
110 NULL, /* base_init */
111 NULL, /* base_finalize */
112 (GClassInitFunc)captive_private_bcb_pin_object_class_init,
113 NULL, /* class_finalize */
114 NULL, /* class_data */
115 sizeof(CaptivePrivateBcbPinObject),
117 (GInstanceInitFunc)captive_private_bcb_pin_object_init,
120 captive_private_bcb_pin_object_type=g_type_register_static(CAPTIVE_PRIVATE_BCB_TYPE_OBJECT,
121 "CaptivePrivateBcbPinObject",&captive_private_bcb_pin_object_info,0);
124 return captive_private_bcb_pin_object_type;
128 static guint captive_private_bcb_pin_object_hash_new_hash_func(const guint64 *offsetp)
130 return (*offsetp)^((*offsetp)>>32);
133 static gboolean captive_private_bcb_pin_object_hash_new_key_compare_func(const guint64 *offset_ap,const guint64 *offset_bp)
135 return (*offset_ap)==(*offset_bp);
138 GHashTable *captive_private_bcb_pin_object_hash_new(void)
140 return g_hash_table_new(
141 (GHashFunc)captive_private_bcb_pin_object_hash_new_hash_func,
142 (GEqualFunc)captive_private_bcb_pin_object_hash_new_key_compare_func);
145 void captive_private_bcb_pin_object_hash_destroy(GHashTable *pin_hash)
147 g_return_if_fail(pin_hash!=NULL);
149 g_hash_table_destroy(pin_hash);
152 static void captive_private_bcb_pin_object_validate(CaptivePrivateBcbPinObject *captive_private_bcb_pin_object)
156 g_return_if_fail(CAPTIVE_PRIVATE_BCB_PIN_IS_OBJECT(captive_private_bcb_pin_object));
157 g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(
158 CAPTIVE_PRIVATE_BCB_OBJECT(captive_private_bcb_pin_object)->SharedCacheMap));
160 start=captive_private_bcb_pin_object->offset;
161 end =captive_private_bcb_pin_object->offset+PAGE_SIZE;
163 g_assert(end<=CAPTIVE_ROUND_UP64(
164 CAPTIVE_PRIVATE_BCB_OBJECT(captive_private_bcb_pin_object)->SharedCacheMap->AllocationSize,PAGE_SIZE));
167 static void captive_private_bcb_pin_object_FileSizes_changed(CaptiveSharedCacheMapObject *captive_shared_cache_map_object,
168 guint64 AllocationSize,guint64 FileSize,guint64 ValidDataLength,
169 CaptivePrivateBcbPinObject *captive_private_bcb_pin_object /* user_data */)
171 g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object));
172 g_return_if_fail(CAPTIVE_PRIVATE_BCB_PIN_IS_OBJECT(captive_private_bcb_pin_object));
173 g_return_if_fail(CAPTIVE_PRIVATE_BCB_OBJECT(captive_private_bcb_pin_object)->SharedCacheMap
174 ==captive_shared_cache_map_object);
176 /* 'AllocationSize' must not change if any map/pin Bcbs exist. */
177 g_assert(AllocationSize==captive_shared_cache_map_object->AllocationSize);
180 static void captive_private_bcb_pin_object_purge(CaptiveSharedCacheMapObject *captive_shared_cache_map_object,
181 CaptivePrivateBcbPinObject *captive_private_bcb_pin_object /* user_data */)
183 g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object));
184 g_return_if_fail(CAPTIVE_PRIVATE_BCB_PIN_IS_OBJECT(captive_private_bcb_pin_object));
185 g_return_if_fail(CAPTIVE_PRIVATE_BCB_OBJECT(captive_private_bcb_pin_object)->SharedCacheMap
186 ==captive_shared_cache_map_object);
188 g_assert(!captive_shared_cache_map_is_page_dirty(captive_shared_cache_map_object,
189 captive_private_bcb_pin_object->offset));
192 static void captive_private_bcb_pin_object_FileSizes_changed_after(CaptiveSharedCacheMapObject *captive_shared_cache_map_object,
193 guint64 AllocationSize,guint64 FileSize,guint64 ValidDataLength,
194 CaptivePrivateBcbPinObject *captive_private_bcb_pin_object /* user_data */)
196 g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object));
197 g_return_if_fail(CAPTIVE_PRIVATE_BCB_PIN_IS_OBJECT(captive_private_bcb_pin_object));
198 g_return_if_fail(CAPTIVE_PRIVATE_BCB_OBJECT(captive_private_bcb_pin_object)->SharedCacheMap
199 ==captive_shared_cache_map_object);
201 /* we are 'g_signal_connect_after' */
202 g_assert(AllocationSize ==captive_shared_cache_map_object->AllocationSize);
203 g_assert(FileSize ==captive_shared_cache_map_object->FileSize);
204 g_assert(ValidDataLength==captive_shared_cache_map_object->ValidDataLength);
206 captive_private_bcb_pin_object_validate(captive_private_bcb_pin_object);
209 void _captive_private_bcb_pin_object_connect_SharedCacheMap
210 (CaptivePrivateBcbPinObject *captive_private_bcb_pin_object,CaptiveSharedCacheMapObject *captive_shared_cache_map_object)
212 g_return_if_fail(CAPTIVE_PRIVATE_BCB_PIN_IS_OBJECT(captive_private_bcb_pin_object));
213 g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object));
214 g_return_if_fail(CAPTIVE_PRIVATE_BCB_OBJECT(captive_private_bcb_pin_object)->SharedCacheMap==NULL);
216 _captive_private_bcb_object_connect_SharedCacheMap(
217 CAPTIVE_PRIVATE_BCB_OBJECT(captive_private_bcb_pin_object),captive_shared_cache_map_object);
219 captive_private_bcb_pin_object->FileSizes_changed_handler_id=g_signal_connect(
220 captive_shared_cache_map_object,"FileSizes_changed",
221 G_CALLBACK(captive_private_bcb_pin_object_FileSizes_changed),
222 captive_private_bcb_pin_object);
223 g_assert(captive_private_bcb_pin_object->FileSizes_changed_handler_id>=1);
224 captive_private_bcb_pin_object->FileSizes_changed_after_handler_id=g_signal_connect_after(
225 captive_shared_cache_map_object,"FileSizes_changed",
226 G_CALLBACK(captive_private_bcb_pin_object_FileSizes_changed_after),
227 captive_private_bcb_pin_object);
228 g_assert(captive_private_bcb_pin_object->FileSizes_changed_after_handler_id>=1);
229 captive_private_bcb_pin_object->purge_handler_id=g_signal_connect(
230 captive_shared_cache_map_object,"purge",
231 G_CALLBACK(captive_private_bcb_pin_object_purge),
232 captive_private_bcb_pin_object);
233 g_assert(captive_private_bcb_pin_object->purge_handler_id>=1);
236 CaptivePrivateBcbPinObject *captive_private_bcb_pin_object_new(CaptiveSharedCacheMapObject *captive_shared_cache_map_object,
239 CaptivePrivateBcbPinObject *captive_private_bcb_pin_object;
241 g_return_val_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object),NULL);
242 g_return_val_if_fail(0==CAPTIVE_ROUND_DOWN_EXCEEDING64(offset,PAGE_SIZE),NULL);
244 g_assert(captive_shared_cache_map_object->PinAccess);
246 captive_private_bcb_pin_object=g_object_new(
247 CAPTIVE_PRIVATE_BCB_PIN_TYPE_OBJECT, /* object_type */
248 NULL); /* first_property_name; FIXME: support properties */
250 captive_private_bcb_pin_object->offset=offset;
252 _captive_private_bcb_pin_object_connect_SharedCacheMap(captive_private_bcb_pin_object,
253 captive_shared_cache_map_object);
255 g_assert(captive_shared_cache_map_object->pin_hash!=NULL);
256 g_assert(!g_hash_table_lookup(captive_shared_cache_map_object->pin_hash,
257 &captive_private_bcb_pin_object->offset));
258 g_hash_table_insert(captive_shared_cache_map_object->pin_hash,
259 &captive_private_bcb_pin_object->offset,
260 captive_private_bcb_pin_object);
262 return captive_private_bcb_pin_object;
265 CaptivePrivateBcbPinObject *captive_private_bcb_pin_object_get(CaptiveSharedCacheMapObject *captive_shared_cache_map_object,
268 CaptivePrivateBcbPinObject *captive_private_bcb_pin_object;
270 g_return_val_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object),NULL);
271 g_return_val_if_fail(0==CAPTIVE_ROUND_DOWN_EXCEEDING64(offset,PAGE_SIZE),NULL);
273 if ((captive_private_bcb_pin_object=g_hash_table_lookup(captive_shared_cache_map_object->pin_hash,
275 g_assert(CAPTIVE_PRIVATE_BCB_PIN_IS_OBJECT(captive_private_bcb_pin_object));
276 return captive_private_bcb_pin_object;
281 CaptivePrivateBcbPinObject *captive_private_bcb_pin_object_get_ref(CaptiveSharedCacheMapObject *captive_shared_cache_map_object,
284 CaptivePrivateBcbPinObject *captive_private_bcb_pin_object;
286 g_return_val_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object),NULL);
287 g_return_val_if_fail(0==CAPTIVE_ROUND_DOWN_EXCEEDING64(offset,PAGE_SIZE),NULL);
289 if ((captive_private_bcb_pin_object=captive_private_bcb_pin_object_get(captive_shared_cache_map_object,offset))) {
290 g_assert(CAPTIVE_PRIVATE_BCB_PIN_IS_OBJECT(captive_private_bcb_pin_object));
291 g_object_ref(captive_private_bcb_pin_object);
292 return captive_private_bcb_pin_object;
294 return captive_private_bcb_pin_object_new(captive_shared_cache_map_object,offset);
297 gboolean captive_private_bcb_pin_object_is_dirty(CaptivePrivateBcbPinObject *captive_private_bcb_pin_object)
299 g_return_val_if_fail(CAPTIVE_PRIVATE_BCB_PIN_IS_OBJECT(captive_private_bcb_pin_object),FALSE);
300 g_return_val_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(
301 CAPTIVE_PRIVATE_BCB_OBJECT(captive_private_bcb_pin_object)->SharedCacheMap),FALSE);
303 return captive_shared_cache_map_is_page_dirty(CAPTIVE_PRIVATE_BCB_OBJECT(captive_private_bcb_pin_object)->SharedCacheMap,
304 captive_private_bcb_pin_object->offset);
307 void captive_private_bcb_pin_object_flush(CaptivePrivateBcbPinObject *captive_private_bcb_pin_object)
309 g_return_if_fail(CAPTIVE_PRIVATE_BCB_PIN_IS_OBJECT(captive_private_bcb_pin_object));
310 g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(
311 CAPTIVE_PRIVATE_BCB_OBJECT(captive_private_bcb_pin_object)->SharedCacheMap));
312 g_return_if_fail(captive_private_bcb_pin_object_is_dirty(captive_private_bcb_pin_object));
314 /* Flush synchronously here. */
315 captive_shared_cache_map_flush(CAPTIVE_PRIVATE_BCB_OBJECT(captive_private_bcb_pin_object)->SharedCacheMap,
316 captive_private_bcb_pin_object->offset,
317 captive_private_bcb_pin_object->offset+PAGE_SIZE);
320 void captive_private_bcb_pin_object_set_dirty(CaptivePrivateBcbPinObject *captive_private_bcb_pin_object)
322 g_return_if_fail(CAPTIVE_PRIVATE_BCB_PIN_IS_OBJECT(captive_private_bcb_pin_object));
323 g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(
324 CAPTIVE_PRIVATE_BCB_OBJECT(captive_private_bcb_pin_object)->SharedCacheMap));
326 captive_shared_cache_map_set_dirty(CAPTIVE_PRIVATE_BCB_OBJECT(captive_private_bcb_pin_object)->SharedCacheMap,
327 captive_private_bcb_pin_object->offset,
328 captive_private_bcb_pin_object->offset+PAGE_SIZE);
331 void captive_private_bcb_pin_object_set_lsn(CaptivePrivateBcbPinObject *captive_private_bcb_pin_object,gint64 lsn)
333 g_return_if_fail(CAPTIVE_PRIVATE_BCB_PIN_IS_OBJECT(captive_private_bcb_pin_object));
334 g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(
335 CAPTIVE_PRIVATE_BCB_OBJECT(captive_private_bcb_pin_object)->SharedCacheMap));
337 captive_shared_cache_map_page_set_lsn(CAPTIVE_PRIVATE_BCB_OBJECT(captive_private_bcb_pin_object)->SharedCacheMap,
338 captive_private_bcb_pin_object->offset,lsn);
341 void captive_private_bcb_pin_object_detach_pin(CaptivePrivateBcbPinObject *captive_private_bcb_pin_object)
343 CaptiveSharedCacheMapObject *SharedCacheMap;
345 g_return_if_fail(CAPTIVE_PRIVATE_BCB_PIN_IS_OBJECT(captive_private_bcb_pin_object));
347 SharedCacheMap=captive_private_bcb_object_get_SharedCacheMap(CAPTIVE_PRIVATE_BCB_OBJECT(captive_private_bcb_pin_object));
348 g_assert(SharedCacheMap->pin_hash!=NULL);
349 g_assert(captive_private_bcb_pin_object==g_hash_table_lookup(SharedCacheMap->pin_hash,
350 &captive_private_bcb_pin_object->offset));
351 g_hash_table_remove(SharedCacheMap->pin_hash,&captive_private_bcb_pin_object->offset);