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