1 /***********************************************************************/
2 /* Open Visualization Data Explorer */
3 /* (C) Copyright IBM Corp. 1989,1999 */
4 /* ALL RIGHTS RESERVED */
5 /* This code licensed under the */
6 /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */
7 /***********************************************************************/
8
9 #include <dxconfig.h>
10
11 #if defined(HAVE_STRING_H)
12 #include <string.h>
13 #endif
14
15 #include <dx/dx.h>
16 #include "pendingcmds.h"
17
18 static PendingCmdList *
_dxf_getPendingCmdList()19 _dxf_getPendingCmdList()
20 {
21 Private p = (Private)DXGetCacheEntry(PJL_KEY, 0, 0);
22 if (! p)
23 return NULL;
24 else return (PendingCmdList *)DXGetPrivateData(p);
25 }
26
27 void
_dxf_release_PendingCmdList(PendingCmdList * p)28 _dxf_release_PendingCmdList(PendingCmdList *p)
29 {
30 if (p)
31 DXDelete(p->exprivate);
32 }
33
34 Error
_dxf_delete_PendingCmdList(Pointer d)35 _dxf_delete_PendingCmdList(Pointer d)
36 {
37 int i;
38 PendingCmdList *pjl = (PendingCmdList *)d;
39 PendingCmd *p;
40
41 for (i = 0, p = pjl->pendingCmdList;
42 i < pjl->pendingCmdListSize; i++, p++)
43 {
44 DXFree(p->major);
45 DXFree(p->minor);
46 DXDelete((Object)p->data);
47
48 p->major = NULL;
49 p->minor = NULL;
50 p->data = NULL;
51 }
52
53 DXFree(pjl->pendingCmdList);
54 DXFree(pjl);
55
56 return OK;
57 }
58
59 static PendingCmdList *
_dxf_newPendingCmdList()60 _dxf_newPendingCmdList()
61 {
62 Private p;
63 PendingCmdList *pjl;
64
65 pjl = DXAllocate(sizeof(PendingCmdList));
66 if (! pjl)
67 return NULL;
68
69 pjl->pendingCmdListSize = 0;
70 pjl->pendingCmdListMax = 10;
71
72 pjl->pendingCmdList = DXAllocate(10*sizeof(PendingCmd));
73
74 if (! pjl->pendingCmdList)
75 {
76 DXFree(pjl);
77 return NULL;
78 }
79
80 p = DXNewPrivate((Pointer)pjl, _dxf_delete_PendingCmdList);
81 if (! p)
82 {
83 DXFree(pjl->pendingCmdList);
84 DXFree(pjl);
85 return NULL;
86 }
87
88 if (! DXSetCacheEntry((Object)p, CACHE_PERMANENT, PJL_KEY, 0, 0))
89 {
90 DXDelete((Object)p);
91 DXFree(pjl->pendingCmdList);
92 DXFree(pjl);
93 return NULL;
94 }
95
96 pjl->exprivate = DXReference((Object)p);
97
98 return pjl;
99 }
100
101 static Error
_dxf_growPendingCmdList(PendingCmdList * pjl)102 _dxf_growPendingCmdList(PendingCmdList *pjl)
103 {
104 int n = pjl->pendingCmdListMax * 2;
105
106 pjl->pendingCmdList = DXReAllocate((Pointer)(pjl->pendingCmdList),
107 n*sizeof(PendingCmd));
108
109 if (! pjl->pendingCmdList)
110 return ERROR;
111
112 pjl->pendingCmdListMax = n;
113
114 return OK;
115 }
116
117 Error
DXSetPendingCmd(char * major,char * minor,int (* job)(Private),Private data)118 DXSetPendingCmd(char *major, char *minor, int (*job)(Private), Private data)
119 {
120 int i;
121 PendingCmd *p;
122 PendingCmdList *pjl = _dxf_getPendingCmdList();
123
124 if (!pjl){
125 if (!job)
126 return OK;
127 else
128 if (NULL == (pjl = _dxf_newPendingCmdList()))
129 goto error;
130 }
131
132 for (i = 0, p = pjl->pendingCmdList;
133 i < pjl->pendingCmdListSize; i++, p++)
134 {
135 /*
136 * Ignore any already-deleted tasks
137 */
138 if (p->job)
139 {
140 if (!strcmp(p->major, major) &&
141 ((minor == NULL && p->minor == NULL) ||
142 !strcmp(p->minor, minor)))
143 {
144 if (job)
145 {
146 p->job = job;
147 p->data = (Private)DXReference((Object)data);
148 goto done;
149 }
150 else
151 {
152 DXFree(p->major);
153 DXFree(p->minor);
154 DXDelete((Object)p->data);
155 p->job = NULL;
156 goto done;
157 }
158 }
159 }
160 }
161
162 if (pjl->pendingCmdListSize == pjl->pendingCmdListMax)
163 if (! _dxf_growPendingCmdList(pjl))
164 goto error;
165
166 p = pjl->pendingCmdList + pjl->pendingCmdListSize++;
167
168 p->major = DXAllocate(strlen(major) + 1);
169 if (! p->major)
170 {
171 p->minor = NULL;
172 goto error;
173 }
174
175 strncpy(p->major, major, strlen(major) + 1);
176
177 if (minor)
178 {
179 p->minor = DXAllocate(strlen(minor) + 1);
180 if (! p->minor)
181 goto error;
182
183 strncpy(p->minor, minor, strlen(minor) + 1);
184 }
185 else
186 p->minor = NULL;
187
188 p->job = job;
189 p->data = data;
190
191 done:
192 _dxf_release_PendingCmdList(pjl);
193 return OK;
194
195 error:
196 _dxf_release_PendingCmdList(pjl);
197 return ERROR;
198 }
199
200 Error
_dxf_RunPendingCmds()201 _dxf_RunPendingCmds()
202 {
203 int i, j;
204 PendingCmdList *pjl = _dxf_getPendingCmdList();
205
206 if (!pjl)
207 goto done;
208
209 for (i = 0; i < pjl->pendingCmdListSize; i++)
210 if (! (pjl->pendingCmdList[i].job)(pjl->pendingCmdList[i].data))
211 goto error;
212
213 /*
214 * Compress it, removing deleted entries
215 */
216 for (i = j = 0; i < pjl->pendingCmdListSize; i++)
217 if (pjl->pendingCmdList[i].job)
218 {
219 if (i != j)
220 pjl->pendingCmdList[j] = pjl->pendingCmdList[i];
221 j++;
222 }
223
224 pjl->pendingCmdListSize = j;
225
226 done:
227 _dxf_release_PendingCmdList(pjl);
228 return OK;
229
230 error:
231 _dxf_release_PendingCmdList(pjl);
232 return ERROR;
233 }
234
235 Error
_dxf_CleanupPendingCmdList()236 _dxf_CleanupPendingCmdList()
237 {
238 DXSetCacheEntry(NULL, CACHE_PERMANENT, PJL_KEY, 0, 0);
239 return OK;
240 }
241