1 /**
2 *
3 * $Id: Cache.c,v 1.1 2004/08/28 19:22:43 dannybackx Exp $
4 *
5 * Copyright (C) 1995 Free Software Foundation, Inc.
6 * Copyright (C) 1995-2001 LessTif Development Team
7 *
8 * This file is part of the GNU LessTif Library.
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Library General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU Library General Public
21 * License along with this library; if not, write to the Free
22 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 **/
25
26 static const char rcsid[] = "$Id: Cache.c,v 1.1 2004/08/28 19:22:43 dannybackx Exp $";
27
28 #include <LTconfig.h>
29
30 #include <string.h>
31
32 #include <XmI/XmI.h>
33
34 #include <Xm/XmP.h>
35 #include <Xm/CacheP.h>
36 #include <Xm/ExtObjectP.h>
37
38 #include <XmI/DebugUtil.h>
39
40
41 void
_XmCacheDelete(XtPointer data)42 _XmCacheDelete(XtPointer data)
43 {
44 XmGadgetCacheRefPtr node;
45
46 node = (XmGadgetCacheRefPtr)DataToGadgetCache(data);
47 node->cache.ref_count--;
48
49 DEBUGOUT(_LtDebug(__FILE__, NULL, "Deleting %p : %08x: refcount: %d\n",
50 data, node, node->cache.ref_count));
51
52 if (node->cache.ref_count == 0)
53 {
54 DEBUGOUT(_LtDebug(__FILE__, NULL,
55 "Ref count 0: deleting %08x\n", node));
56
57 node->cache.prev->next = node->cache.next;
58
59 if (node->cache.next != NULL) /* rws 16 Jun 1997
60 This is not the correct solution
61 since the node never gets freed, but
62 it does stop a core dump in one of
63 my apps
64 */
65 {
66 node->cache.next->prev = node->cache.prev;
67 XtFree((char *)node);
68 }
69 else
70 {
71 _XmWarning(NULL,
72 "Cache.c:_XmCacheDelete - node->cache.next is NULL");
73 }
74 }
75 }
76
77 void
_XmCacheCopy(XtPointer src,XtPointer dest,size_t size)78 _XmCacheCopy(XtPointer src, XtPointer dest, size_t size)
79 {
80 memcpy(dest, src, size);
81 }
82
83 XtPointer
_XmCachePart(XmCacheClassPartPtr cp,XtPointer cpart,size_t size)84 _XmCachePart(XmCacheClassPartPtr cp, XtPointer cpart, size_t size)
85 {
86 XmGadgetCachePtr list;
87 XtPointer newpart;
88
89 DEBUGOUT(_LtDebug(__FILE__, NULL,
90 "Attempting to cache a part %p head: %p.\n", cpart,
91 &ClassCacheHead(cp)));
92
93 /*
94 * Guess what. Motif doesn't save memory and self link the initial node.
95 * Big surprise.
96 */
97 if (ClassCacheHead(cp).next == NULL)
98 {
99 ClassCacheHead(cp).prev = &ClassCacheHead(cp);
100 ClassCacheHead(cp).next = &ClassCacheHead(cp);
101 ClassCacheHead(cp).ref_count = -1;
102 }
103
104 /* search cache */
105 list = ClassCacheHead(cp).next;
106
107 while (list != &ClassCacheHead(cp))
108 {
109 XmGadgetCachePtr tmp;
110
111 if (ClassCacheCompare(cp) (cpart, CacheDataPtr(list)))
112 {
113 DEBUGOUT(_LtDebug(__FILE__, NULL,
114 "Cache hit: %08x\n", CacheDataPtr(list)));
115
116 if (cpart != CacheDataPtr(list))
117 {
118 list->ref_count++;
119 }
120
121 return CacheDataPtr(list);
122 }
123
124 tmp = list->next;
125
126 if (cpart == CacheDataPtr(list))
127 {
128 DEBUGOUT(_LtDebug(__FILE__, NULL,
129 "In cache, but invalid. Deleting old entry.\n"));
130
131 _XmCacheDelete(cpart);
132 }
133
134 list = tmp;
135 }
136
137 /* not in cache, add new entry */
138 list = (XmGadgetCachePtr)XtCalloc(1, sizeof(XmGadgetCache) + size);
139
140 DEBUGOUT(_LtDebug(__FILE__, NULL,
141 "Not in cache. Adding new entry of size %d: %p.\n", size, list));
142
143 newpart = (XtPointer)((char *)list + sizeof(XmGadgetCache));
144
145 list->prev = ClassCacheHead(cp).prev;
146 ClassCacheHead(cp).prev->next = list;
147
148 list->next = &ClassCacheHead(cp);
149 ClassCacheHead(cp).prev = list;
150
151 list->ref_count = 1;
152
153 DEBUGOUT(_LtDebug(__FILE__, NULL,
154 "Next: %p Prev: %p\n", list->prev, list->next));
155
156 ClassCacheCopy(cp) (cpart, (XtPointer)newpart, size);
157
158 return newpart;
159 }
160