ilbmtoicon: Refuse to generate icons with differently sized select and normal images
[AROS.git] / rom / exec / exec_util.c
blob70b2f7b6affbac43ff4f48b7818ec78227ec6e79
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Exec utility functions.
6 Lang: english
7 */
9 #include <aros/debug.h>
10 #include <exec/lists.h>
11 #include <exec/tasks.h>
12 #include <exec/memory.h>
13 #include <exec/execbase.h>
14 #include <dos/dosextens.h>
16 #include <proto/exec.h>
18 #include "etask.h"
19 #include "exec_intern.h"
20 #include "exec_util.h"
21 #include "taskstorage.h"
23 /*****************************************************************************
25 NAME */
26 #include "exec_util.h"
28 struct ETask * Exec_FindChild(
30 /* SYNOPSIS */
31 ULONG id,
32 struct ExecBase *SysBase)
34 /* FUNCTION
35 Scan through the current tasks children list searching for the task
36 whose et_UniqueID field matches.
38 INPUTS
39 id - The task ID to match.
41 RESULT
42 Address of the ETask structure that matches, or
43 NULL otherwise.
45 NOTES
47 EXAMPLE
49 BUGS
51 SEE ALSO
53 INTERNALS
55 ******************************************************************************/
57 struct ETask *et;
58 struct ETask *thisET;
60 thisET = GetETask(FindTask(NULL));
61 if (thisET != NULL)
63 ForeachNode (&thisET->et_Children, et)
65 if (et->et_UniqueID == id)
66 return et;
68 ForeachNode(&thisET->et_TaskMsgPort.mp_MsgList, et)
70 if (et->et_UniqueID == id)
71 return et;
74 return NULL;
77 BOOL
78 Exec_InitETask(struct Task *task, struct ExecBase *SysBase)
80 struct Task *thistask = FindTask(NULL);
82 * We don't add this to the task memory, it isn't free'd by
83 * RemTask(), rather by somebody else calling ChildFree().
84 * Alternatively, an orphaned task will free its own ETask.
86 struct ETask *et =
87 AllocMem(sizeof(struct IntETask), MEMF_PUBLIC | MEMF_CLEAR);
88 D(bug("[TSS] Create new ETask=%p for task=%p with size %d\n",
89 et, task, sizeof(struct IntETask)));
91 task->tc_UnionETask.tc_ETask = et;
92 if (!et)
93 return FALSE;
94 task->tc_Flags |= TF_ETASK;
96 if (thistask != NULL)
98 /* Clone parent's TaskStorage */
99 struct ETask *thiset = GetETask(thistask);
100 if (thiset) {
101 IPTR *thists = thiset->et_TaskStorage;
103 if (thists) {
104 IPTR *ts = AllocMem(thists[__TS_FIRSTSLOT] * sizeof(thists[0]), MEMF_ANY);
105 if (!ts) {
106 FreeMem(et, sizeof(struct IntETask));
107 return FALSE;
109 CopyMem(thists, ts, thists[__TS_FIRSTSLOT] * sizeof(thists[0]));
110 et->et_TaskStorage = ts;
115 et->et_Parent = thistask;
116 NEWLIST(&et->et_Children);
118 /* Initialise the message list */
119 InitMsgPort(&et->et_TaskMsgPort);
120 et->et_TaskMsgPort.mp_SigTask = task;
121 et->et_TaskMsgPort.mp_SigBit = SIGB_CHILD;
123 /* Initialise the trap fields */
124 et->et_TrapAlloc = SysBase->TaskTrapAlloc;
125 et->et_TrapAble = 0;
127 #ifdef DEBUG_ETASK
129 int len = strlen(task->tc_Node.ln_Name) + 1;
130 IntETask(et)->iet_Me = AllocVec(len, MEMF_CLEAR|MEMF_PUBLIC);
131 if (IntETask(et)->iet_Me != NULL)
132 CopyMem(task->tc_Node.ln_Name, IntETask(et)->iet_Me, len);
134 #endif
136 /* Get a unique identifier for this task */
137 Forbid();
138 while(et->et_UniqueID == 0)
141 * Add some fuzz on wrapping. It's likely that the early numbers
142 * where taken by somebody else.
144 if(++SysBase->ex_TaskID == 0)
145 SysBase->ex_TaskID = 1024;
147 Disable();
148 if (FindTaskByPID(SysBase->ex_TaskID) == NULL)
149 et->et_UniqueID = SysBase->ex_TaskID;
150 Enable();
152 Permit();
154 /* Finally if the parent task is an ETask, add myself as its child */
155 if(et->et_Parent && ((struct Task*) et->et_Parent)->tc_Flags & TF_ETASK)
157 Forbid();
158 ADDHEAD(&GetETask(et->et_Parent)->et_Children, et);
159 Permit();
162 return TRUE;
165 void
166 Exec_CleanupETask(struct Task *task, struct ExecBase *SysBase)
168 struct ETask *et = NULL, *child, *nextchild, *parent;
169 struct Node *tmpNode;
170 BOOL expunge = TRUE;
172 if(task->tc_Flags & TF_ETASK)
173 et = task->tc_UnionETask.tc_ETask;
174 if(!et)
175 return;
177 D(bug("CleanupETask: task=%x, et=%x\n", task, et));
179 Forbid();
181 /* Clean up after all the children that the task didn't do itself. */
182 ForeachNodeSafe(&et->et_TaskMsgPort.mp_MsgList, child, tmpNode)
184 ExpungeETask(child);
187 /* If we have an ETask parent, tell it we have exited. */
188 if(et->et_Parent != NULL)
190 parent = GetETask(et->et_Parent);
192 /* Link children to our parent. */
193 ForeachNodeSafe(&et->et_Children, child, nextchild)
195 child->et_Parent = et->et_Parent;
196 //Forbid();
197 if (parent)
198 ADDTAIL(&parent->et_Children, child);
199 //Permit();
202 /* Notify parent only if child was created with NP_NotifyOnDeath set
203 to TRUE */
204 if(parent != NULL)
206 REMOVE(et);
209 (((struct Task *)task)->tc_Node.ln_Type == NT_PROCESS) &&
210 (((struct Process*) task)->pr_Flags & PRF_NOTIFYONDEATH)
213 PutMsg(&parent->et_TaskMsgPort, (struct Message *)et);
214 expunge = FALSE;
218 else
220 /* Orphan all our remaining children. */
221 ForeachNode(&et->et_Children, child)
222 child->et_Parent = NULL;
225 if(expunge)
226 ExpungeETask(et);
228 Permit();
231 void
232 Exec_ExpungeETask(struct ETask *et, struct ExecBase *SysBase)
234 IPTR *ts = et->et_TaskStorage;
236 if(et->et_Result2)
237 FreeVec(et->et_Result2);
239 #ifdef DEBUG_ETASK
240 FreeVec(IntETask(et)->iet_Me);
241 #endif
242 D(bug("Exec_ExpungeETask: Freeing et=%x, ts=%x, size=%d\n",
243 et, ts, ts ? (ULONG)ts[__TS_FIRSTSLOT] : 0
245 FreeMem(et, sizeof(struct IntETask));
246 if (ts)
247 FreeMem(ts, ts[__TS_FIRSTSLOT] * sizeof(ts[0]));
250 BOOL Exec_CheckTask(struct Task *task, struct ExecBase *SysBase)
252 struct Task *t;
254 if (!task)
255 return FALSE;
257 Forbid();
259 if (task == SysBase->ThisTask)
261 Permit();
262 return TRUE;
265 ForeachNode(&SysBase->TaskReady, t)
267 if (task == t)
269 Permit();
270 return TRUE;
274 ForeachNode(&SysBase->TaskWait, t)
276 if (task == t)
278 Permit();
279 return TRUE;
283 Permit();
284 return FALSE;