2 Copyright © 2012, The AROS Development Team. All rights reserved.
6 #define MUIMASTER_YES_INLINE_STDARG
8 #include <clib/alib_protos.h>
9 #include <proto/intuition.h>
10 #include <proto/muimaster.h>
11 #include <proto/utility.h>
12 #include <proto/dos.h>
15 #include "muimaster_intern.h"
17 #include "support_classes.h"
18 #include "process_private.h"
23 #define DELAYTICKS (10)
26 extern struct Library
*MUIMasterBase
;
29 static void my_process(void)
31 // invokes MUIM_Process_Process for the the class/object specified by
32 // MUIA_Process_SourceClass/Object (source class may be NULL)
34 D(bug("[Process.mui] my_process called\n"));
36 struct Task
*thistask
= FindTask(NULL
);
37 struct Process_DATA
*data
= thistask
->tc_UserData
;
39 if (data
->sourceclass
)
41 CoerceMethod(data
->sourceclass
, data
->sourceobject
,
42 MUIM_Process_Process
, &data
->kill
, data
->self
);
46 DoMethod(data
->sourceobject
, MUIM_Process_Process
, &data
->kill
,
50 data
->task
= NULL
; // show MUIM_Process_Kill that we're done
52 D(bug("[Process.mui] my_process terminated\n"));
56 IPTR
Process__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
58 struct Process_DATA
*data
;
59 struct TagItem
*tag
, *tags
;
60 struct Task
*thistask
;
62 obj
= (Object
*) DoSuperMethodA(cl
, obj
, (Msg
) msg
);
66 data
= INST_DATA(cl
, obj
);
71 data
->autolaunch
= TRUE
;
72 data
->stacksize
= 40000;
73 thistask
= FindTask(NULL
);
74 data
->priority
= thistask
->tc_Node
.ln_Pri
;
76 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
));)
80 case MUIA_Process_AutoLaunch
:
81 data
->autolaunch
= tag
->ti_Data
;
84 case MUIA_Process_Name
:
85 data
->name
= (STRPTR
) tag
->ti_Data
;
88 case MUIA_Process_Priority
:
89 data
->priority
= tag
->ti_Data
;
92 case MUIA_Process_SourceClass
:
93 data
->sourceclass
= (struct IClass
*)tag
->ti_Data
;
96 case MUIA_Process_SourceObject
:
97 data
->sourceobject
= (Object
*) tag
->ti_Data
;
100 case MUIA_Process_StackSize
:
101 data
->stacksize
= tag
->ti_Data
;
106 D(bug("muimaster.library/process.c: Process Object created at 0x%lx\n",
109 if (data
->autolaunch
)
111 DoMethod(obj
, MUIM_Process_Launch
);
118 IPTR
Process__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
120 #define STORE *(msg->opg_Storage)
122 struct Process_DATA
*data
= INST_DATA(cl
, obj
);
126 switch (msg
->opg_AttrID
)
128 case MUIA_Process_Task
:
129 STORE
= (IPTR
) data
->task
;
133 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
138 IPTR
Process__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
140 D(bug("[Process.mui/OM_DISPOSE]\n"));
142 // struct Process_DATA *data = INST_DATA(cl, obj);
144 DoMethod(obj
, MUIM_Process_Kill
, 0);
146 return DoSuperMethodA(cl
, obj
, msg
);
150 IPTR
Process__MUIM_Process_Kill(struct IClass
*cl
, Object
*obj
,
151 struct MUIP_Process_Kill
*msg
)
153 D(bug("[MUIM_Process_Kill] maxdelay %d\n", msg
->maxdelay
));
155 struct Process_DATA
*data
= INST_DATA(cl
, obj
);
159 // send SIGBREAKF_CTRL_C
160 // wait until it has terminated
162 // Stops process' loop (MUIM_Process_Process). If the loop
163 // is not running does nothing.
165 // msg->maxdelay == 0 means "wait forever"
167 data
->kill
= 1; // stops the loop in Class4.c demo
169 // the spawned task sets data->task to NULL on exit
170 while (data
->task
!= NULL
)
172 Signal((struct Task
*)data
->task
, SIGBREAKF_CTRL_C
);
175 D(bug("[MUIM_Process_Kill] delay %d maxdelay %d\n", delay
,
177 if ((msg
->maxdelay
!= 0) && (delay
> msg
->maxdelay
))
179 D(bug("[MUIM_Process_Kill] timeout\n"));
185 D(bug("[MUIM_Process_Kill] retval %d\n", retval
));
191 IPTR
Process__MUIM_Process_Launch(struct IClass
*cl
, Object
*obj
,
192 struct MUIP_Process_Launch
*msg
)
194 D(bug("[MUIM_Process_Launch]\n"));
196 struct Process_DATA
*data
= INST_DATA(cl
, obj
);
198 // Starts process's loop (MUIM_Process_Process). If the loop
199 // is already running does nothing.
201 if (data
->task
== NULL
)
203 struct TagItem tags
[] = {
204 {NP_Entry
, (IPTR
) my_process
},
205 {NP_StackSize
, data
->stacksize
},
206 {data
->name
? NP_Name
: TAG_IGNORE
,
208 {NP_Priority
, data
->priority
},
209 {NP_UserData
, (IPTR
) data
},
213 data
->task
= CreateNewProc(tags
);
220 IPTR
Process__MUIM_Process_Process(struct IClass
*cl
, Object
*obj
,
221 struct MUIP_Process_Process
*msg
)
223 D(bug("[MUIM_Process_Process] kill %p proc %p\n", msg
->kill
,
226 // struct Process_DATA *data = INST_DATA(cl, obj);
228 // Main process method. Terminating condition is passed in message struct.
229 // Proper implementation should wait for a signal to not use 100% cpu.
230 // This is some kind of a virtual function. Sub-class implementators
231 // must overwrite it.
233 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
237 IPTR
Process__MUIM_Process_Signal(struct IClass
*cl
, Object
*obj
,
238 struct MUIP_Process_Signal
*msg
)
240 D(bug("[MUIM_Process_Signal] sigs %u\n", msg
->sigs
));
242 struct Process_DATA
*data
= INST_DATA(cl
, obj
);
244 // just send an arbitrary signal to the spawned process.
247 Signal((struct Task
*)data
->task
, msg
->sigs
);
254 #if ZUNE_BUILTIN_PROCESS
255 BOOPSI_DISPATCHER(IPTR
, Process_Dispatcher
, cl
, obj
, msg
)
257 switch (msg
->MethodID
)
260 return Process__OM_NEW(cl
, obj
, (struct opSet
*)msg
);
262 return Process__OM_SET(cl
, obj
, (struct opSet
*)msg
);
264 return Process__OM_DISPOSE(cl
, obj
, msg
);
265 case MUIM_Process_Kill
:
266 return Process__MUIM_Process_Kill(cl
, obj
,
267 (struct MUIP_Process_Kill
*)msg
);
268 case MUIM_Process_Launch
:
269 return Process__MUIM_Process_Launch(cl
, obj
,
270 (struct MUIP_Process_Launch
*)msg
);
271 case MUIM_Process_Process
:
272 return Process__MUIM_Process_Process(cl
, obj
,
273 (struct MUIP_Process_Process
*)msg
);
274 case MUIM_Process_Signal
:
275 return Process__MUIM_Process_Signal(cl
, obj
,
276 (struct MUIP_Process_Signal
*)msg
);
278 return DoSuperMethodA(cl
, obj
, msg
);
281 BOOPSI_DISPATCHER_END
283 const struct __MUIBuiltinClass _MUI_Process_desc
=
287 sizeof(struct Process_DATA
),
288 (void *) Process_Dispatcher
290 #endif /* ZUNE_BUILTIN_PROCESS */