forwarding build fix when MUIA_Scrollgroup_AutoBars is defined (NicJA).
[AROS-Contrib.git] / scalos / main / ChildProcess.c
blob8f47a00b95837662d27f3f9cad6a59c9f1a50ebb
1 // ChildProcess.c
2 // $Date$
3 // $Revision$
6 #include <exec/types.h>
7 #include <utility/hooks.h>
8 #include <workbench/workbench.h>
9 #include <workbench/startup.h>
10 #include <dos/dostags.h>
11 #include <dos/datetime.h>
13 #define __USE_SYSBASE
15 #include <proto/dos.h>
16 #include <proto/exec.h>
17 #include <proto/utility.h>
18 #include "debug.h"
19 #include <proto/scalos.h>
21 #include <clib/alib_protos.h>
23 #include <defs.h>
24 #include <scalos/scalos.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
30 #include "scalos_structures.h"
31 #include "functions.h"
32 #include "Variables.h"
34 //----------------------------------------------------------------------------
36 // local data structures
38 //----------------------------------------------------------------------------
40 // local data items
42 //----------------------------------------------------------------------------
44 // local functions
46 static SAVEDS(void) INTERRUPT ProcRunnerTask(void);
48 //----------------------------------------------------------------------------
50 // NumLongs : number of longwords in ArgArray (!!not number of entries!!)
51 BOOL RunProcess(struct ScaWindowTask *wt, RUNPROCFUNC Routine, ULONG NumLongs,
52 struct WBArg *ArgArray, struct MsgPort *ReplyPort)
54 BOOL Success = FALSE;
55 struct SM_RunProcess *msg;
56 ULONG NumBytes;
58 d1(kprintf("%s/%s/%ld: START wt=%08lx Routine=%08lx NumLongs=%lu ArgArray=%08lx ReplyPort=%08lx\n", \
59 __FILE__, __FUNC__, __LINE__, wt, Routine, NumLongs, ArgArray, ReplyPort));
61 if (NumLongs > 77)
62 return FALSE;
64 NumBytes = NumLongs * sizeof(ULONG);
66 msg = (struct SM_RunProcess *) SCA_AllocMessage(MTYP_RunProcess, NumBytes);
67 if (msg)
69 msg->ScalosMessage.sm_Message.mn_ReplyPort = ReplyPort;
70 msg->WindowTask = wt;
71 msg->EntryPoint = Routine;
73 if (NumBytes > 0)
74 CopyMem(ArgArray, &msg->Flags, NumBytes);
76 d1(KPrintF("%s/%s/%ld: msg=%08lx iwt=%08lx Routine=%08lx\n", __FILE__, __FUNC__, __LINE__, msg, wt, Routine));
78 Success = ChildProcessRun((struct internalScaWindowTask *) wt,
79 &msg->ScalosMessage,
80 NP_Priority, 0,
81 NP_Name, (IPTR) "Scalos_SubProcess_Runner",
82 TAG_END);
85 d1(kprintf("%s/%s/%ld: Success=%ld\n", __FILE__, __FUNC__, __LINE__, Success));
87 return Success;
90 //----------------------------------------------------------------------------
92 BOOL ChildProcessRun(struct internalScaWindowTask *iwt, struct ScalosMessage *msg, Tag FirstTag, ...)
94 va_list args;
95 struct TagItem *TagList = NULL;
96 BOOL Success = FALSE;
97 struct SM_StartChildProcess *mStart = NULL;
98 struct MsgPort *StartReplyPort;
100 d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__));
102 va_start(args, FirstTag);
104 do {
105 STATIC_PATCHFUNC(ProcRunnerTask)
106 struct Process *newProc;
107 BPTR WBPath;
109 StartReplyPort = CreateMsgPort();
110 if (NULL == StartReplyPort)
111 break;
113 mStart = (struct SM_StartChildProcess *) SCA_AllocMessage(MTYP_StartChildProcess, 0);
114 if (NULL == mStart)
115 break;
117 mStart->ScalosMessage.sm_Message.mn_ReplyPort = StartReplyPort;
118 mStart->smscp_WindowTask = &iwt->iwt_WindowTask;
120 TagList = ScalosVTagList(FirstTag, args);
121 if (NULL == TagList)
122 break;
124 ScalosObtainSemaphoreShared(&iwt->iwt_ChildProcessSemaphore);
126 WBPath = DupWBPathList();
127 d1(kprintf("%s/%s/%ld: WBPath=%08lx\n", __FILE__, __FUNC__, __LINE__, WBPath));
129 newProc = CreateNewProcTags(NP_WindowPtr, NULL,
130 NP_StackSize, CurrentPrefs.pref_DefaultStackSize,
131 NP_Cli, TRUE,
132 NP_Entry, (IPTR) PATCH_NEWFUNC(ProcRunnerTask),
133 WBPath ? NP_Path : TAG_IGNORE, WBPath,
134 TAG_MORE, TagList,
135 TAG_END);
137 d1(kprintf("%s/%s/%ld: newProc=%08lx\n", __FILE__, __FUNC__, __LINE__, newProc));
139 if (NULL == newProc)
141 ScalosReleaseSemaphore(&iwt->iwt_ChildProcessSemaphore);
142 break;
145 d1(kprintf("%s/%s/%ld: sending SM_StartChildProcess\n", __FILE__, __FUNC__, __LINE__));
147 PutMsg(&newProc->pr_MsgPort, &mStart->ScalosMessage.sm_Message);
149 d1(kprintf("%s/%s/%ld: wait for SM_StartChildProcess reply\n", __FILE__, __FUNC__, __LINE__));
151 // wait for message reply fro child process
152 WaitPort(StartReplyPort);
153 mStart = (struct SM_StartChildProcess *) GetMsg(StartReplyPort);
155 d1(kprintf("%s/%s/%ld: SM_StartChildProcess reply received - mStart=%08lx\n", __FILE__, __FUNC__, __LINE__, mStart));
157 if (NULL == mStart)
159 ScalosReleaseSemaphore(&iwt->iwt_ChildProcessSemaphore);
160 break;
163 // keep semaphore locked until we have received the SM_StartChildProcess
164 // and know that the child process has locked the semaphore
165 ScalosReleaseSemaphore(&iwt->iwt_ChildProcessSemaphore);
167 d1(kprintf("%s/%s/%ld: send SM_RunProcess msg=%08lx\n", __FILE__, __FUNC__, __LINE__, msg));
169 PutMsg(&newProc->pr_MsgPort, &msg->sm_Message);
170 msg = NULL;
172 Success = TRUE;
173 d1(kprintf("%s/%s/%ld: Success=%ld\n", __FILE__, __FUNC__, __LINE__, Success));
174 } while (0);
176 if (StartReplyPort)
177 DeleteMsgPort(StartReplyPort);
178 if (mStart)
179 SCA_FreeMessage(&mStart->ScalosMessage);
180 if (TagList)
181 FreeTagItems(TagList);
182 if (msg)
183 SCA_FreeMessage(msg);
185 va_end(args);
187 d1(kprintf("%s/%s/%ld: END Success=%ld\n", __FILE__, __FUNC__, __LINE__, Success));
189 return Success;
192 //----------------------------------------------------------------------------
194 // SubProcess Runner Task
195 static SAVEDS(void) INTERRUPT ProcRunnerTask(void)
197 struct Process *myProc = (struct Process *) FindTask(NULL);
198 struct internalScaWindowTask *iwt = NULL;
199 struct SM_StartChildProcess *mStart;
200 struct SM_RunProcess *msg;
202 d1(kprintf("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__));
204 // Scalos MUST not quit while subprocess is running
205 ScalosObtainSemaphoreShared(&QuitSemaphore);
207 d1(kprintf("%s/%s/%ld: wait for MTYP_StartChildProcess\n", __FILE__, __FUNC__, __LINE__));
209 // First, wait for MTYP_StartChildProcess message and reply it
210 do {
211 WaitPort(&myProc->pr_MsgPort);
212 mStart = (struct SM_StartChildProcess *) GetMsg(&myProc->pr_MsgPort);
214 d1(kprintf("%s/%s/%ld: mStart=%08lx\n", __FILE__, __FUNC__, __LINE__, mStart));
215 if (mStart)
217 iwt = (struct internalScaWindowTask *) mStart->smscp_WindowTask;
219 d1(kprintf("%s/%s/%ld: MTYP_StartChildProcess received - iwt=%08lx\n", __FILE__, __FUNC__, __LINE__, iwt));
221 if (iwt)
223 ScalosObtainSemaphoreShared(&iwt->iwt_ChildProcessSemaphore);
226 ReplyMsg(&mStart->ScalosMessage.sm_Message);
228 } while (NULL == mStart);
230 d1(kprintf("%s/%s/%ld: wait for SM_RunProcess - iwt=%08lx\n", __FILE__, __FUNC__, __LINE__, iwt));
232 do {
233 WaitPort(&myProc->pr_MsgPort);
234 msg = (struct SM_RunProcess *) GetMsg(&myProc->pr_MsgPort);
235 } while (NULL == msg);
237 d1(KPrintF("%s/%s/%ld: SM_RunProcess received - msg=%08lx ReplyPort=%08lx Len=%lu\n", \
238 __FILE__, __FUNC__, __LINE__, msg, msg->ScalosMessage.sm_Message.mn_ReplyPort, \
239 msg->ScalosMessage.sm_Message.mn_Length));
241 if (ID_IMSG == msg->ScalosMessage.sm_Signature)
243 struct SM_AsyncBackFill *smab;
245 switch (msg->ScalosMessage.sm_MessageType)
247 case MTYP_RunProcess:
248 d1(kprintf("%s/%s/%ld: MTYP_RunProcess msg=%08lx iwt=%08lx\n", __FILE__, __FUNC__, __LINE__, msg, iwt));
250 (msg->EntryPoint)(&msg->Flags, msg);
251 break;
253 case MTYP_AsyncBackFill:
254 smab = (struct SM_AsyncBackFill *) msg;
256 d1(KPrintF("%s/%s/%ld: MTYP_AsyncBackFill msg=%08lx ReplyPort=%08lx iwt=%08lx\n", __FILE__, __FUNC__, __LINE__, smab, msg->ScalosMessage.sm_Message.mn_ReplyPort, iwt));
257 d1(KPrintF("%s/%s/%ld: smab_BackfillFunc=%08lx\n", __FILE__, __FUNC__, __LINE__, smab->smab_BackfillFunc));
259 (smab->smab_BackfillFunc)(NULL, msg);
260 break;
262 default:
263 d1(kprintf("%s/%s/%ld: unkown sm_MessageType=%ld msg=%08lx iwt=%08lx\n", \
264 __FILE__, __FUNC__, __LINE__, msg->ScalosMessage.sm_MessageType, msg, iwt));
265 break;
268 d1(KPrintF("%s/%s/%ld: msg=%08lx ReplyPort=%08lx MsgType=%08lx\n", \
269 __FILE__, __FUNC__, __LINE__, msg, msg->ScalosMessage.sm_Message.mn_ReplyPort, msg->ScalosMessage.sm_MessageType));
272 d1(KPrintF("%s/%s/%ld: msg=%08lx ReplyPort=%08lx\n", __FILE__, __FUNC__, __LINE__, msg, msg->ScalosMessage.sm_Message.mn_ReplyPort));
274 if (msg->ScalosMessage.sm_Message.mn_ReplyPort)
276 d1(Forbid(); KPrintF("%s/%s/%ld: MsgList Head=%08lx TailPred=%08lx\n", \
277 __FILE__, __FUNC__, __LINE__, msg->ScalosMessage.sm_Message.mn_ReplyPort->mp_MsgList.lh_Head, \
278 msg->ScalosMessage.sm_Message.mn_ReplyPort->mp_MsgList.lh_TailPred); Permit());
280 ReplyMsg(&msg->ScalosMessage.sm_Message);
282 d1(Forbid(); KPrintF("%s/%s/%ld: MsgList Head=%08lx Succ=%08lx TailPred=%08lx Pred=%08lx\n", \
283 __FILE__, __FUNC__, __LINE__, \
284 msg->ScalosMessage.sm_Message.mn_ReplyPort->mp_MsgList.lh_Head, \
285 msg->ScalosMessage.sm_Message.mn_ReplyPort->mp_MsgList.lh_Head->ln_Succ, \
286 msg->ScalosMessage.sm_Message.mn_ReplyPort->mp_MsgList.lh_TailPred, \
287 msg->ScalosMessage.sm_Message.mn_ReplyPort->mp_MsgList.lh_TailPred->ln_Pred); Permit());
289 else
290 SCA_FreeMessage(&msg->ScalosMessage);
292 if (iwt)
294 d1(kprintf("%s/%s/%ld: iwt=%08lx\n", __FILE__, __FUNC__, __LINE__, iwt));
295 ScalosReleaseSemaphore(&iwt->iwt_ChildProcessSemaphore);
298 d1(kprintf("%s/%s/%ld: iwt=%08lx\n", __FILE__, __FUNC__, __LINE__, iwt));
300 ScalosReleaseSemaphore(&QuitSemaphore);
302 d1(kprintf("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__));
305 //----------------------------------------------------------------------------